diff --git a/org.eclipse.egit.core.test/META-INF/MANIFEST.MF b/org.eclipse.egit.core.test/META-INF/MANIFEST.MF
index cd9ff83..e4e24f9 100644
--- a/org.eclipse.egit.core.test/META-INF/MANIFEST.MF
+++ b/org.eclipse.egit.core.test/META-INF/MANIFEST.MF
@@ -15,15 +15,15 @@
  org.mockito;bundle-version="[1.8.0,1.9.0)",
  org.hamcrest;bundle-version="[1.1.0,2.0.0)"
 Bundle-ActivationPolicy: lazy
-Import-Package: org.mockito;version="[1.8.0,1.9.0)",
- org.mockito.stubbing;version="[1.8.0,1.9.0)",
- org.eclipse.egit.core;version="[3.0.0,3.1.0)",
- org.eclipse.egit.core.op;version="[3.0.0,3.1.0)",
- org.eclipse.egit.core.project;version="[3.0.0,3.1.0)",
+Import-Package: org.eclipse.egit.core.internal;version="[3.0.0,3.1.0)",
+ org.eclipse.egit.core.internal.op;version="[3.0.0,3.1.0)",
+ org.eclipse.egit.core.internal.project;version="[3.0.0,3.1.0)",
  org.eclipse.jgit.api.errors;version="[3.0.0,3.1.0)",
  org.eclipse.jgit.junit;version="[3.0.0,3.1.0)",
  org.eclipse.jgit.lib;version="[3.0.0,3.1.0)",
  org.eclipse.jgit.treewalk;version="[3.0.0,3.1.0)",
  org.eclipse.jgit.treewalk.filter;version="[3.0.0,3.1.0)",
- org.eclipse.jgit.util;version="[3.0.0,3.1.0)"
+ org.eclipse.jgit.util;version="[3.0.0,3.1.0)",
+ org.mockito;version="[1.8.0,1.9.0)",
+ org.mockito.stubbing;version="[1.8.0,1.9.0)"
 Bundle-RequiredExecutionEnvironment: J2SE-1.5
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/GitMoveDeleteHookTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/GitMoveDeleteHookTest.java
deleted file mode 100644
index a0d4c32..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/GitMoveDeleteHookTest.java
+++ /dev/null
@@ -1,675 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2011, Robin Rosenberg
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- */
-package org.eclipse.egit.core;
-
-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 static org.junit.Assert.fail;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.eclipse.core.filesystem.URIUtil;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IProjectDescription;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.core.op.AddToIndexOperation;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.core.test.TestProject;
-import org.eclipse.egit.core.test.TestRepository;
-import org.eclipse.egit.core.test.TestUtils;
-import org.eclipse.jgit.dircache.DirCache;
-import org.eclipse.jgit.dircache.DirCacheBuilder;
-import org.eclipse.jgit.dircache.DirCacheEntry;
-import org.eclipse.jgit.errors.CorruptObjectException;
-import org.eclipse.jgit.junit.MockSystemReader;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.lib.FileMode;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.internal.storage.file.FileRepository;
-import org.eclipse.jgit.util.FS;
-import org.eclipse.jgit.util.FileUtils;
-import org.eclipse.jgit.util.SystemReader;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * All sorts of interesting cases
- */
-public class GitMoveDeleteHookTest {
-
-	TestUtils testUtils = new TestUtils();
-
-	TestRepository testRepository;
-
-	Repository repository;
-
-	Set<File> testDirs = new HashSet<File>();
-
-	File workspaceSupplement;
-
-	File workspace;
-
-	@Before
-	public void setUp() throws Exception {
-		Activator.getDefault().getRepositoryCache().clear();
-		MockSystemReader mockSystemReader = new MockSystemReader();
-		SystemReader.setInstance(mockSystemReader);
-		mockSystemReader.setProperty(Constants.GIT_CEILING_DIRECTORIES_KEY,
-				ResourcesPlugin.getWorkspace().getRoot().getLocation().toFile()
-						.getAbsoluteFile().toString());
-		workspaceSupplement = testUtils.createTempDir("wssupplement");
-		workspace = ResourcesPlugin.getWorkspace().getRoot().getLocation().toFile().getAbsoluteFile();
-	}
-
-	@After
-	public void tearDown() throws IOException, CoreException {
-		if (testRepository != null)
-			testRepository.dispose();
-		repository = null;
-		for (File d : testDirs)
-			if (d.exists())
-				FileUtils.delete(d, FileUtils.RECURSIVE | FileUtils.RETRY);
-		ResourcesPlugin.getWorkspace().getRoot().delete(IResource.FORCE, null);
-	}
-
-	private TestProject initRepoInsideProjectInsideWorkspace() throws IOException,
-			CoreException {
-		TestProject project = new TestProject(true, "Project-1", true, workspaceSupplement);
-		File gitDir = new File(project.getProject().getLocationURI().getPath(),
-				Constants.DOT_GIT);
-		testDirs.add(gitDir);
-		testRepository = new TestRepository(gitDir);
-		repository = testRepository.getRepository();
-		testRepository.connect(project.getProject());
-		registerWorkspaceRelativeTestDir("Project-1");
-		return project;
-	}
-
-	private TestProject initRepoInsideProjectOutsideWorkspace()
-			throws IOException, CoreException {
-		TestProject project = new TestProject(true, "Project-1", false,
-				workspaceSupplement);
-		File gitDir = new File(project.getProject().getLocationURI().getPath(),
-				Constants.DOT_GIT);
-		testDirs.add(gitDir);
-		testRepository = new TestRepository(gitDir);
-		repository = testRepository.getRepository();
-		testRepository.connect(project.getProject());
-		return project;
-	}
-
-	private TestProject initRepoAboveProjectInsideWs(String srcParent, String d)
-	throws IOException, CoreException {
-		return initRepoAboveProject(srcParent, d, true);
-	}
-
-	private TestProject initRepoAboveProject(String srcParent, String d, boolean insidews)
-			throws IOException, CoreException {
-		registerWorkspaceRelativeTestDir(srcParent);
-		TestProject project = new TestProject(true, srcParent + "Project-1", insidews, workspaceSupplement);
-		File gd = new File(insidews?workspace:workspaceSupplement, d);
-
-		File gitDir = new File(gd, Constants.DOT_GIT);
-		testDirs.add(gitDir);
-		testRepository = new TestRepository(gitDir);
-		repository = testRepository.getRepository();
-		testRepository.connect(project.getProject());
-		return project;
-	}
-
-	@Test
-	public void testDeleteFile() throws Exception {
-		TestProject project = initRepoInsideProjectInsideWorkspace();
-		testUtils.addFileToProject(project.getProject(), "file.txt",
-				"some text");
-		testUtils.addFileToProject(project.getProject(), "file2.txt",
-				"some  more text");
-		AddToIndexOperation addToIndexOperation = new AddToIndexOperation(
-				new IResource[] { project.getProject().getFile("file.txt"),
-						project.getProject().getFile("file2.txt") });
-		addToIndexOperation.execute(null);
-
-		// Validate pre-conditions
-		DirCache dirCache = DirCache.read(repository.getIndexFile(),
-				FS.DETECTED);
-		assertEquals(2, dirCache.getEntryCount());
-		assertNotNull(dirCache.getEntry("file.txt"));
-		assertNotNull(dirCache.getEntry("file2.txt"));
-		// Modify the content before the move
-		testUtils.changeContentOfFile(project.getProject(), project
-				.getProject().getFile("file.txt"), "other text");
-		project.getProject().getFile("file.txt").delete(true, null);
-
-		// Check index for the deleted file
-		dirCache.read();
-		assertEquals(1, dirCache.getEntryCount());
-		assertNull(dirCache.getEntry("file.txt"));
-		assertNotNull(dirCache.getEntry("file2.txt"));
-		// Actual file is deleted
-		assertFalse(project.getProject().getFile("file.txt").exists());
-		// But a non-affected file remains
-		assertTrue(project.getProject().getFile("file2.txt").exists());
-	}
-
-	@Test
-	public void testDeleteFolder() throws Exception {
-		TestProject project = initRepoInsideProjectInsideWorkspace();
-		testUtils.addFileToProject(project.getProject(), "folder/file.txt",
-				"some text");
-		testUtils.addFileToProject(project.getProject(), "folder2/file.txt",
-				"some other text");
-		AddToIndexOperation addToIndexOperation = new AddToIndexOperation(
-				new IResource[] {
-						project.getProject().getFile("folder/file.txt"),
-						project.getProject().getFile("folder2/file.txt") });
-		addToIndexOperation.execute(null);
-
-		DirCache dirCache = DirCache.read(repository.getIndexFile(),
-				FS.DETECTED);
-		assertNotNull(dirCache.getEntry("folder/file.txt"));
-		assertNotNull(dirCache.getEntry("folder2/file.txt"));
-		// Modify the content before the move
-		testUtils.changeContentOfFile(project.getProject(), project
-				.getProject().getFile("folder/file.txt"), "other text");
-		project.getProject().getFolder("folder").delete(true, null);
-
-		dirCache.read();
-		// Unlike delete file, dircache is untouched... pretty illogical
-		// TODO: Change the behavior of the hook.
-		assertNotNull(dirCache.getEntry("folder/file.txt"));
-		// Not moved file still there
-		assertNotNull(dirCache.getEntry("folder2/file.txt"));
-	}
-
-	@Test
-	public void testDeleteProject() throws Exception {
-		TestProject project = initRepoAboveProjectInsideWs("P/", "");
-		testUtils.addFileToProject(project.getProject(), "file.txt",
-				"some text");
-		AddToIndexOperation addToIndexOperation = new AddToIndexOperation(
-				new IResource[] { project.getProject().getFile("file.txt") });
-		addToIndexOperation.execute(null);
-
-		RepositoryMapping mapping = RepositoryMapping.getMapping(project
-				.getProject());
-		IPath gitDirAbsolutePath = mapping.getGitDirAbsolutePath();
-		Repository db = new FileRepository(gitDirAbsolutePath.toFile());
-		DirCache index = DirCache.read(db.getIndexFile(), db.getFS());
-		assertNotNull(index.getEntry("P/Project-1/file.txt"));
-		db.close();
-		db = null;
-		project.getProject().delete(true, null);
-		assertNull(RepositoryMapping.getMapping(project.getProject()));
-		// Check that the repo is still there. Being a bit paranoid we look for
-		// a file
-		assertTrue(gitDirAbsolutePath.toString(),
-				gitDirAbsolutePath.append("HEAD").toFile().exists());
-
-		db = new FileRepository(gitDirAbsolutePath.toFile());
-		index = DirCache.read(db.getIndexFile(), db.getFS());
-		// FIXME: Shouldn't we unstage deleted projects?
-		assertNotNull(index.getEntry("P/Project-1/file.txt"));
-		db.close();
-	}
-
-	@Test
-	public void testMoveFile() throws Exception {
-		TestProject project = initRepoInsideProjectInsideWorkspace();
-		testUtils.addFileToProject(project.getProject(), "file.txt",
-				"some text");
-		testUtils.addFileToProject(project.getProject(), "file2.txt",
-				"some  more text");
-		AddToIndexOperation addToIndexOperation = new AddToIndexOperation(
-				new IResource[] { project.getProject().getFile("file.txt"),
-						project.getProject().getFile("file2.txt") });
-		addToIndexOperation.execute(null);
-
-		// Validate pre-conditions
-		DirCache dirCache = DirCache.read(repository.getIndexFile(),
-				FS.DETECTED);
-		assertNotNull(dirCache.getEntry("file.txt"));
-		assertNotNull(dirCache.getEntry("file2.txt"));
-		assertNull(dirCache.getEntry("data.txt"));
-		assertFalse(project.getProject().getFile("data.txt").exists());
-		ObjectId oldContentId = dirCache.getEntry("file.txt").getObjectId();
-		// Modify the content before the move
-		testUtils.changeContentOfFile(project.getProject(), project
-				.getProject().getFile("file.txt"), "other text");
-		project.getProject()
-				.getFile("file.txt")
-				.move(project.getProject().getFile("data.txt").getFullPath(),
-						false, null);
-
-		dirCache.read();
-		assertTrue(project.getProject().getFile("data.txt").exists());
-		assertNotNull(dirCache.getEntry("data.txt"));
-		// Same content in index as before the move
-		assertEquals(oldContentId, dirCache.getEntry("data.txt").getObjectId());
-
-		// Not moved file still in its old place
-		assertNotNull(dirCache.getEntry("file2.txt"));
-	}
-
-	/**
-	 * Rename "folder" to "dir".
-	 *
-	 * @throws Exception
-	 */
-	@Test
-	public void testMoveFolder() throws Exception {
-		TestProject project = initRepoInsideProjectInsideWorkspace();
-		testUtils.addFileToProject(project.getProject(), "folder/file.txt",
-				"some text");
-		testUtils.addFileToProject(project.getProject(), "folder2/file.txt",
-				"some other text");
-		AddToIndexOperation addToIndexOperation = new AddToIndexOperation(
-				new IResource[] {
-						project.getProject().getFile("folder/file.txt"),
-						project.getProject().getFile("folder2/file.txt") });
-		addToIndexOperation.execute(null);
-
-		DirCache dirCache = DirCache.read(repository.getIndexFile(),
-				FS.DETECTED);
-		assertNotNull(dirCache.getEntry("folder/file.txt"));
-		assertNotNull(dirCache.getEntry("folder2/file.txt"));
-		assertNull(dirCache.getEntry("dir/file.txt"));
-		assertFalse(project.getProject().getFile("dir/file.txt").exists());
-		ObjectId oldContentId = dirCache.getEntry("folder/file.txt")
-				.getObjectId();
-		// Modify the content before the move
-		testUtils.changeContentOfFile(project.getProject(), project
-				.getProject().getFile("folder/file.txt"), "other text");
-		project.getProject()
-				.getFolder("folder")
-				.move(project.getProject().getFolder("dir").getFullPath(),
-						false, null);
-
-		dirCache.read();
-		assertTrue(project.getProject().getFile("dir/file.txt").exists());
-		assertNull(dirCache.getEntry("folder/file.txt"));
-		assertNotNull(dirCache.getEntry("dir/file.txt"));
-		// Same content in index as before the move
-		assertEquals(oldContentId, dirCache.getEntry("dir/file.txt")
-				.getObjectId());
-		// Not moved file still there
-		assertNotNull(dirCache.getEntry("folder2/file.txt"));
-	}
-
-	/**
-	 * Rename and move a project in the workspace containing a Git repository.
-	 * <p>
-	 * The repository will be moved with the project.
-	 * Note that there is no way to rename a project in the workspace without
-	 * moving it. See https://bugs.eclipse.org/358828 for a discussion.
-	 *
-	 * @throws Exception
-	 */
-	@Test
-	public void testMoveAndRenameProjectContainingGitRepo() throws Exception {
-		ResourcesPlugin.getWorkspace().getRoot().getProject("Project-1").delete(true, null);
-		ResourcesPlugin.getWorkspace().getRoot().getProject("P2").delete(true, null);
-
-		TestProject project = initRepoInsideProjectInsideWorkspace();
-		testUtils.addFileToProject(project.getProject(), "file.txt",
-				"some text");
-		AddToIndexOperation addToIndexOperation = new AddToIndexOperation(
-				new IResource[] { project.getProject().getFile("file.txt") });
-		addToIndexOperation.execute(null);
-		IProjectDescription description = project.getProject().getDescription();
-		description.setName("P2");
-		registerWorkspaceRelativeTestDir("P2");
-		project.getProject().move(description,
-				IResource.FORCE | IResource.SHALLOW, null);
-		IProject project2 = ResourcesPlugin.getWorkspace().getRoot()
-				.getProject("P2");
-		assertNotNull(RepositoryMapping.getMapping(project2.getProject()));
-		Repository movedRepo = RepositoryMapping.getMapping(project2)
-				.getRepository();
-		assertEquals("P2",
-				movedRepo.getDirectory().getParentFile()
-						.getName());
-		DirCache dc = movedRepo.readDirCache();
-		assertEquals(1, dc.getEntryCount());
-		assertEquals("file.txt", dc.getEntry(0).getPathString());
-
-		assertFalse(ResourcesPlugin.getWorkspace().getRoot().getProject("Project-1").exists());
-	}
-
-	/**
-	 * Rename a project outside the workspace containing a Git repository.
-	 * <p>
-	 * Note the similarity of the code with {@link #testMoveAndRenameProjectContainingGitRepo()}
-	 *
-	 * @throws Exception
-	 */
-	@Test
-	public void testRenameProjectOutsideWorkspaceContainingGitRepo() throws Exception {
-		ResourcesPlugin.getWorkspace().getRoot().getProject("Project-1").delete(true, null);
-		ResourcesPlugin.getWorkspace().getRoot().getProject("P2").delete(true, null);
-		TestProject project = initRepoInsideProjectOutsideWorkspace();
-		testUtils.addFileToProject(project.getProject(), "file.txt",
-				"some text");
-		AddToIndexOperation addToIndexOperation = new AddToIndexOperation(
-				new IResource[] { project.getProject().getFile("file.txt") });
-		addToIndexOperation.execute(null);
-		IProjectDescription description = project.getProject().getDescription();
-		description.setName("P2");
-		project.getProject().move(description,
-				IResource.FORCE | IResource.SHALLOW, null);
-		IProject project2 = ResourcesPlugin.getWorkspace().getRoot()
-				.getProject("P2");
-		assertNotNull(RepositoryMapping.getMapping(project2.getProject()));
-		Repository movedRepo = RepositoryMapping.getMapping(project2)
-				.getRepository();
-		assertEquals("Project-1",
-				movedRepo.getDirectory().getParentFile()
-						.getName());
-		DirCache dc = movedRepo.readDirCache();
-		assertEquals(1, dc.getEntryCount());
-		assertEquals("file.txt", dc.getEntry(0).getPathString());
-
-		assertFalse(ResourcesPlugin.getWorkspace().getRoot().getProject("Project-1").exists());
-	}
-
-	/**
-	 * Move a project outside the workspace containing a Git repository, but do not rename it.
-	 * <p>
-	 * Note the similarity of the code with {@link #testMoveAndRenameProjectContainingGitRepo()}
-	 *
-	 * @throws Exception
-	 */
-	@Test
-	public void testMoveButDoNotRenameProjectOutsideWorkspaceContainingGitRepo() throws Exception {
-		ResourcesPlugin.getWorkspace().getRoot().getProject("Project-1").delete(true, null);
-		ResourcesPlugin.getWorkspace().getRoot().getProject("P2").delete(true, null);
-		TestProject project = initRepoInsideProjectOutsideWorkspace();
-		testUtils.addFileToProject(project.getProject(), "file.txt",
-				"some text");
-		AddToIndexOperation addToIndexOperation = new AddToIndexOperation(
-				new IResource[] { project.getProject().getFile("file.txt") });
-		addToIndexOperation.execute(null);
-		IProjectDescription description = project.getProject().getDescription();
-		description.setLocationURI(URIUtil.toURI(new Path(new File(project.getWorkspaceSupplement(), "P2").getAbsolutePath())));
-		project.getProject().move(description,
-				IResource.FORCE | IResource.SHALLOW, null);
-		IProject project2 = ResourcesPlugin.getWorkspace().getRoot()
-				.getProject("Project-1"); // same name
-		assertNotNull(RepositoryMapping.getMapping(project2.getProject()));
-		Repository movedRepo = RepositoryMapping.getMapping(project2)
-				.getRepository();
-		assertEquals("P2",
-				movedRepo.getDirectory().getParentFile()
-						.getName());
-		DirCache dc = movedRepo.readDirCache();
-		assertEquals(1, dc.getEntryCount());
-		assertEquals("file.txt", dc.getEntry(0).getPathString());
-
-		assertFalse(ResourcesPlugin.getWorkspace().getRoot().getProject("P2").exists());
-	}
-
-
-	@Test
-	public void testMoveProjectWithinGitRepoMoveAtSameTopLevel()
-			throws Exception {
-		dotestMoveProjectWithinRepoWithinWorkspace("", "Project-1", "", "P2", "");
-	}
-
-	@Test
-	public void testMoveProjectWithinGitRepoMoveFromTopOneLevelDown()
-			throws Exception {
-		dotestMoveProjectWithinRepoWithinWorkspace("", "Project-1", "X/", "P2", "");
-	}
-
-	@Test
-	public void testMoveProjectWithinGitRepoMoveFromOneLevelDownToTop()
-			throws Exception {
-		dotestMoveProjectWithinRepoWithinWorkspace("P/", "Project-1", "", "P2", "");
-	}
-
-	@Test
-	public void testMoveProjectWithinGitRepoMoveFromOneLevelDownToSameDepth()
-			throws Exception {
-		dotestMoveProjectWithinRepoWithinWorkspace("P/", "Project-1", "X/", "P2", "");
-	}
-
-	@Test
-	public void testMoveProjectWithinGitRepoMoveFromOneLevelDownOutsideTheRepo()
-			throws Exception {
-		dotestMoveProjectWithinRepoWithinWorkspace("P/", "Project-1", "P/", "P2", "P/");
-	}
-
-	@Test
-	public void testMoveProjectWithinGitOutsideWorkspaceRepoMoveAtSameTopLevel()
-			throws Exception {
-		dotestMoveProjectWithinRepoOutsideWorkspace("", "Project-1", "", "P2", "");
-	}
-
-	@Test
-	public void testMoveProjectWithinGitOutsideWorkspaceRepoMoveFromTopOneLevelDown()
-			throws Exception {
-		dotestMoveProjectWithinRepoOutsideWorkspace("", "Project-1", "X/", "P2", "");
-	}
-
-	@Test
-	public void testMoveProjectWithinGitOutsideWorkspaceRepoMoveFromOneLevelDownToTop()
-			throws Exception {
-		dotestMoveProjectWithinRepoOutsideWorkspace("P/", "Project-1", "", "P2", "");
-	}
-
-	@Test
-	public void testMoveProjectWithinGitOutsideWorkspaceRepoMoveFromOneLevelDownToSameDepth()
-			throws Exception {
-		dotestMoveProjectWithinRepoOutsideWorkspace("P/", "Project-1", "X/", "P2", "");
-	}
-
-	@Test
-	public void testMoveProjectWithinGitOutsideWorkspaceRepoMoveFromOneLevelDownOutsideTheRepo()
-			throws Exception {
-		dotestMoveProjectWithinRepoOutsideWorkspace("P/", "Project-1", "P/", "P2", "P/");
-	}
-
-
-	@Test
-	public void testMoveProjectWithinGitRepoMoveFromLevelZeroDownOne()
-			throws Exception {
-		// In this case we'd expect the project to move, but not the repository
-		// TODO: Eclipse cannot do this even without the Git plugin either,
-		// TODO: See Bug 307140)
-		try {
-			dotestMoveProjectWithinRepoWithinWorkspace("P/", "Project-1",
-					"P/Project-1/", "P2", "P/Project-1/");
-			if (!"true".equals(System.getProperty("egit.assume_307140_fixed")))
-				fail("ResourceException expected, core functionality dangerously broken and therefore forbidden");
-		} catch (CoreException e) {
-			if ("true".equals(System.getProperty("egit.assume_307140_fixed")))
-				throw e;
-		}
-	}
-
-	@Test
-	public void testMoveFileWithConflictsShouldBeCanceled() throws Exception {
-		TestProject project = initRepoInsideProjectInsideWorkspace();
-		String filePath = "file.txt";
-		IFile file = testUtils.addFileToProject(project.getProject(), filePath, "some text");
-
-		Repository repo = testRepository.getRepository();
-		DirCache index = repo.lockDirCache();
-		DirCacheBuilder builder = index.builder();
-		addUnmergedEntry(filePath, builder);
-		builder.commit();
-
-		try {
-			file.move(new Path("destination.txt"), false, null);
-			fail("Expected move of file with conflicts to fail.");
-		} catch (CoreException e) {
-			IStatus status = e.getStatus();
-			assertNotNull(status);
-			assertEquals(IStatus.WARNING, status.getSeverity());
-		}
-
-		assertTrue("File should still exist at old location", file.exists());
-		DirCache indexAfter = repo.readDirCache();
-		DirCacheEntry entry = indexAfter.getEntry(filePath);
-		assertEquals("Expected entry to still be in non-zero (conflict) stage",
-				DirCacheEntry.STAGE_1, entry.getStage());
-	}
-
-	@Test
-	public void testMoveFolderWithFileWithConflictsShouldBeCanceled() throws Exception {
-		TestProject project = initRepoInsideProjectInsideWorkspace();
-		String filePath = "folder/file.txt";
-		IFile file = testUtils.addFileToProject(project.getProject(), filePath, "some text");
-
-		Repository repo = testRepository.getRepository();
-		DirCache index = repo.lockDirCache();
-		DirCacheBuilder builder = index.builder();
-		addUnmergedEntry(filePath, builder);
-		builder.commit();
-
-		try {
-			project.getProject()
-					.getFolder("folder")
-					.move(project.getProject().getFolder("newfolder")
-							.getFullPath(), false, null);
-			fail("Expected move of folder with file with conflicts to fail.");
-		} catch (CoreException e) {
-			IStatus status = e.getStatus();
-			assertNotNull(status);
-			assertEquals(IStatus.WARNING, status.getSeverity());
-		}
-
-		assertTrue("File should still exist at old location", file.exists());
-		DirCache indexAfter = repo.readDirCache();
-		DirCacheEntry entry = indexAfter.getEntry(filePath);
-		assertEquals("Expected entry to still be in non-zero (conflict) stage",
-				DirCacheEntry.STAGE_1, entry.getStage());
-	}
-
-	private static void addUnmergedEntry(String filePath, DirCacheBuilder builder) {
-		DirCacheEntry stage1 = new DirCacheEntry(filePath, DirCacheEntry.STAGE_1);
-		DirCacheEntry stage2 = new DirCacheEntry(filePath, DirCacheEntry.STAGE_2);
-		DirCacheEntry stage3 = new DirCacheEntry(filePath, DirCacheEntry.STAGE_3);
-		stage1.setFileMode(FileMode.REGULAR_FILE);
-		stage2.setFileMode(FileMode.REGULAR_FILE);
-		stage3.setFileMode(FileMode.REGULAR_FILE);
-		builder.add(stage1);
-		builder.add(stage2);
-		builder.add(stage3);
-	}
-
-	private void dotestMoveProjectWithinRepoWithinWorkspace(String srcParent,
-			String srcProjectName, String dstParent, String dstProjecName,
-			String gitDir) throws CoreException, IOException, Exception,
-			CorruptObjectException {
-		dotestMoveProjectWithinRepo(srcParent, srcProjectName, dstParent, dstProjecName, gitDir, true);
-	}
-
-	private void dotestMoveProjectWithinRepoOutsideWorkspace(String srcParent,
-			String srcProjectName, String dstParent, String dstProjecName,
-			String gitDir) throws CoreException, IOException, Exception,
-			CorruptObjectException {
-		dotestMoveProjectWithinRepo(srcParent, srcProjectName, dstParent, dstProjecName, gitDir, false);
-	}
-
-	private void dotestMoveProjectWithinRepo(String srcParent,
-			String srcProjectName, String dstParent, String dstProjecName,
-			String gitDir, boolean sourceInsideWs) throws IOException, CoreException {
-		String gdRelativeSrcParent = srcParent + srcProjectName + "/";
-		if (gdRelativeSrcParent.startsWith(gitDir))
-			gdRelativeSrcParent = gdRelativeSrcParent
-					.substring(gitDir.length());
-		String gdRelativeDstParent = dstParent + dstProjecName + "/";
-		if (gdRelativeDstParent.startsWith(gitDir))
-			gdRelativeDstParent = gdRelativeDstParent
-					.substring(gitDir.length());
-
-		registerWorkspaceRelativeTestDirProject(srcParent, srcProjectName);
-		registerWorkspaceRelativeTestDirProject(dstParent, dstProjecName);
-
-		// Old cruft may be laying around
-		TestProject project = initRepoAboveProject(srcParent, gitDir, sourceInsideWs);
-		IProject project0 = project.getProject().getWorkspace().getRoot()
-				.getProject(dstProjecName);
-		project0.delete(true, null);
-
-		testUtils.addFileToProject(project.getProject(), "file.txt",
-				"some text");
-		AddToIndexOperation addToIndexOperation = new AddToIndexOperation(
-				new IResource[] { project.getProject().getFile("file.txt") });
-		addToIndexOperation.execute(null);
-
-		// Check condition before move
-		DirCache dirCache = DirCache.read(repository.getIndexFile(),
-				FS.DETECTED);
-		assertNotNull(dirCache.getEntry(gdRelativeSrcParent + "file.txt"));
-		ObjectId oldContentId = dirCache.getEntry(
-				gdRelativeSrcParent + "file.txt").getObjectId();
-
-		// Modify the content before the move, we want to see the staged content
-		// as it was before the move in the index
-		testUtils.changeContentOfFile(project.getProject(), project
-				.getProject().getFile("file.txt"), "other text");
-		IProjectDescription description = project.getProject().getDescription();
-		description.setName(dstProjecName);
-		if (sourceInsideWs)
-			if (dstParent.length() > 0)
-				description.setLocationURI(URIUtil.toURI(project.getProject()
-						.getWorkspace().getRoot().getLocation()
-						.append(dstParent + dstProjecName)));
-			else
-				description.setLocationURI(null);
-		else
-			description.setLocationURI(URIUtil.toURI(new Path(workspaceSupplement + "/" + dstParent + "/" + dstProjecName)));
-		project.getProject().move(description,
-				IResource.FORCE | IResource.SHALLOW, null);
-		IProject project2 = project.getProject().getWorkspace().getRoot()
-				.getProject(dstProjecName);
-		assertTrue(project2.exists());
-		assertNotNull(RepositoryMapping.getMapping(project2));
-
-		// Check that our file exists on disk has a new location in the index
-		dirCache.read();
-		assertTrue(project2.getFile("file.txt").exists());
-		assertNotNull(dirCache.getEntry(gdRelativeDstParent + "file.txt"));
-
-		// Same content in index as before the move, i.e. not same as on disk
-		assertEquals(oldContentId,
-				dirCache.getEntry(gdRelativeDstParent + "file.txt")
-						.getObjectId());
-	}
-
-
-	private void registerWorkspaceRelativeTestDirProject(String parent, String projName) {
-		if ((parent != null) && !parent.equals(""))
-			registerWorkspaceRelativeTestDir(parent);
-		else
-			registerWorkspaceRelativeTestDir(projName);
-	}
-
-	private void registerWorkspaceRelativeTestDir(String relativeDir) {
-		if ((relativeDir != null) && !relativeDir.equals("")) {
-			File d = new File(workspace, relativeDir);
-			testDirs.add(d);
-		}
-	}
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/GitMoveDeleteHookTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/GitMoveDeleteHookTest.java
new file mode 100644
index 0000000..3524ab2
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/GitMoveDeleteHookTest.java
@@ -0,0 +1,676 @@
+/*******************************************************************************
+ * Copyright (C) 2011, Robin Rosenberg
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.eclipse.egit.core.internal;
+
+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 static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.core.filesystem.URIUtil;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.op.AddToIndexOperation;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.egit.core.internal.test.TestProject;
+import org.eclipse.egit.core.internal.test.TestRepository;
+import org.eclipse.egit.core.internal.test.TestUtils;
+import org.eclipse.jgit.dircache.DirCache;
+import org.eclipse.jgit.dircache.DirCacheBuilder;
+import org.eclipse.jgit.dircache.DirCacheEntry;
+import org.eclipse.jgit.errors.CorruptObjectException;
+import org.eclipse.jgit.junit.MockSystemReader;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.FileMode;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.internal.storage.file.FileRepository;
+import org.eclipse.jgit.util.FS;
+import org.eclipse.jgit.util.FileUtils;
+import org.eclipse.jgit.util.SystemReader;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * All sorts of interesting cases
+ */
+public class GitMoveDeleteHookTest {
+
+	TestUtils testUtils = new TestUtils();
+
+	TestRepository testRepository;
+
+	Repository repository;
+
+	Set<File> testDirs = new HashSet<File>();
+
+	File workspaceSupplement;
+
+	File workspace;
+
+	@Before
+	public void setUp() throws Exception {
+		Activator.getDefault().getRepositoryCache().clear();
+		MockSystemReader mockSystemReader = new MockSystemReader();
+		SystemReader.setInstance(mockSystemReader);
+		mockSystemReader.setProperty(Constants.GIT_CEILING_DIRECTORIES_KEY,
+				ResourcesPlugin.getWorkspace().getRoot().getLocation().toFile()
+						.getAbsoluteFile().toString());
+		workspaceSupplement = testUtils.createTempDir("wssupplement");
+		workspace = ResourcesPlugin.getWorkspace().getRoot().getLocation().toFile().getAbsoluteFile();
+	}
+
+	@After
+	public void tearDown() throws IOException, CoreException {
+		if (testRepository != null)
+			testRepository.dispose();
+		repository = null;
+		for (File d : testDirs)
+			if (d.exists())
+				FileUtils.delete(d, FileUtils.RECURSIVE | FileUtils.RETRY);
+		ResourcesPlugin.getWorkspace().getRoot().delete(IResource.FORCE, null);
+	}
+
+	private TestProject initRepoInsideProjectInsideWorkspace() throws IOException,
+			CoreException {
+		TestProject project = new TestProject(true, "Project-1", true, workspaceSupplement);
+		File gitDir = new File(project.getProject().getLocationURI().getPath(),
+				Constants.DOT_GIT);
+		testDirs.add(gitDir);
+		testRepository = new TestRepository(gitDir);
+		repository = testRepository.getRepository();
+		testRepository.connect(project.getProject());
+		registerWorkspaceRelativeTestDir("Project-1");
+		return project;
+	}
+
+	private TestProject initRepoInsideProjectOutsideWorkspace()
+			throws IOException, CoreException {
+		TestProject project = new TestProject(true, "Project-1", false,
+				workspaceSupplement);
+		File gitDir = new File(project.getProject().getLocationURI().getPath(),
+				Constants.DOT_GIT);
+		testDirs.add(gitDir);
+		testRepository = new TestRepository(gitDir);
+		repository = testRepository.getRepository();
+		testRepository.connect(project.getProject());
+		return project;
+	}
+
+	private TestProject initRepoAboveProjectInsideWs(String srcParent, String d)
+	throws IOException, CoreException {
+		return initRepoAboveProject(srcParent, d, true);
+	}
+
+	private TestProject initRepoAboveProject(String srcParent, String d, boolean insidews)
+			throws IOException, CoreException {
+		registerWorkspaceRelativeTestDir(srcParent);
+		TestProject project = new TestProject(true, srcParent + "Project-1", insidews, workspaceSupplement);
+		File gd = new File(insidews?workspace:workspaceSupplement, d);
+
+		File gitDir = new File(gd, Constants.DOT_GIT);
+		testDirs.add(gitDir);
+		testRepository = new TestRepository(gitDir);
+		repository = testRepository.getRepository();
+		testRepository.connect(project.getProject());
+		return project;
+	}
+
+	@Test
+	public void testDeleteFile() throws Exception {
+		TestProject project = initRepoInsideProjectInsideWorkspace();
+		testUtils.addFileToProject(project.getProject(), "file.txt",
+				"some text");
+		testUtils.addFileToProject(project.getProject(), "file2.txt",
+				"some  more text");
+		AddToIndexOperation addToIndexOperation = new AddToIndexOperation(
+				new IResource[] { project.getProject().getFile("file.txt"),
+						project.getProject().getFile("file2.txt") });
+		addToIndexOperation.execute(null);
+
+		// Validate pre-conditions
+		DirCache dirCache = DirCache.read(repository.getIndexFile(),
+				FS.DETECTED);
+		assertEquals(2, dirCache.getEntryCount());
+		assertNotNull(dirCache.getEntry("file.txt"));
+		assertNotNull(dirCache.getEntry("file2.txt"));
+		// Modify the content before the move
+		testUtils.changeContentOfFile(project.getProject(), project
+				.getProject().getFile("file.txt"), "other text");
+		project.getProject().getFile("file.txt").delete(true, null);
+
+		// Check index for the deleted file
+		dirCache.read();
+		assertEquals(1, dirCache.getEntryCount());
+		assertNull(dirCache.getEntry("file.txt"));
+		assertNotNull(dirCache.getEntry("file2.txt"));
+		// Actual file is deleted
+		assertFalse(project.getProject().getFile("file.txt").exists());
+		// But a non-affected file remains
+		assertTrue(project.getProject().getFile("file2.txt").exists());
+	}
+
+	@Test
+	public void testDeleteFolder() throws Exception {
+		TestProject project = initRepoInsideProjectInsideWorkspace();
+		testUtils.addFileToProject(project.getProject(), "folder/file.txt",
+				"some text");
+		testUtils.addFileToProject(project.getProject(), "folder2/file.txt",
+				"some other text");
+		AddToIndexOperation addToIndexOperation = new AddToIndexOperation(
+				new IResource[] {
+						project.getProject().getFile("folder/file.txt"),
+						project.getProject().getFile("folder2/file.txt") });
+		addToIndexOperation.execute(null);
+
+		DirCache dirCache = DirCache.read(repository.getIndexFile(),
+				FS.DETECTED);
+		assertNotNull(dirCache.getEntry("folder/file.txt"));
+		assertNotNull(dirCache.getEntry("folder2/file.txt"));
+		// Modify the content before the move
+		testUtils.changeContentOfFile(project.getProject(), project
+				.getProject().getFile("folder/file.txt"), "other text");
+		project.getProject().getFolder("folder").delete(true, null);
+
+		dirCache.read();
+		// Unlike delete file, dircache is untouched... pretty illogical
+		// TODO: Change the behavior of the hook.
+		assertNotNull(dirCache.getEntry("folder/file.txt"));
+		// Not moved file still there
+		assertNotNull(dirCache.getEntry("folder2/file.txt"));
+	}
+
+	@Test
+	public void testDeleteProject() throws Exception {
+		TestProject project = initRepoAboveProjectInsideWs("P/", "");
+		testUtils.addFileToProject(project.getProject(), "file.txt",
+				"some text");
+		AddToIndexOperation addToIndexOperation = new AddToIndexOperation(
+				new IResource[] { project.getProject().getFile("file.txt") });
+		addToIndexOperation.execute(null);
+
+		RepositoryMapping mapping = RepositoryMapping.getMapping(project
+				.getProject());
+		IPath gitDirAbsolutePath = mapping.getGitDirAbsolutePath();
+		Repository db = new FileRepository(gitDirAbsolutePath.toFile());
+		DirCache index = DirCache.read(db.getIndexFile(), db.getFS());
+		assertNotNull(index.getEntry("P/Project-1/file.txt"));
+		db.close();
+		db = null;
+		project.getProject().delete(true, null);
+		assertNull(RepositoryMapping.getMapping(project.getProject()));
+		// Check that the repo is still there. Being a bit paranoid we look for
+		// a file
+		assertTrue(gitDirAbsolutePath.toString(),
+				gitDirAbsolutePath.append("HEAD").toFile().exists());
+
+		db = new FileRepository(gitDirAbsolutePath.toFile());
+		index = DirCache.read(db.getIndexFile(), db.getFS());
+		// FIXME: Shouldn't we unstage deleted projects?
+		assertNotNull(index.getEntry("P/Project-1/file.txt"));
+		db.close();
+	}
+
+	@Test
+	public void testMoveFile() throws Exception {
+		TestProject project = initRepoInsideProjectInsideWorkspace();
+		testUtils.addFileToProject(project.getProject(), "file.txt",
+				"some text");
+		testUtils.addFileToProject(project.getProject(), "file2.txt",
+				"some  more text");
+		AddToIndexOperation addToIndexOperation = new AddToIndexOperation(
+				new IResource[] { project.getProject().getFile("file.txt"),
+						project.getProject().getFile("file2.txt") });
+		addToIndexOperation.execute(null);
+
+		// Validate pre-conditions
+		DirCache dirCache = DirCache.read(repository.getIndexFile(),
+				FS.DETECTED);
+		assertNotNull(dirCache.getEntry("file.txt"));
+		assertNotNull(dirCache.getEntry("file2.txt"));
+		assertNull(dirCache.getEntry("data.txt"));
+		assertFalse(project.getProject().getFile("data.txt").exists());
+		ObjectId oldContentId = dirCache.getEntry("file.txt").getObjectId();
+		// Modify the content before the move
+		testUtils.changeContentOfFile(project.getProject(), project
+				.getProject().getFile("file.txt"), "other text");
+		project.getProject()
+				.getFile("file.txt")
+				.move(project.getProject().getFile("data.txt").getFullPath(),
+						false, null);
+
+		dirCache.read();
+		assertTrue(project.getProject().getFile("data.txt").exists());
+		assertNotNull(dirCache.getEntry("data.txt"));
+		// Same content in index as before the move
+		assertEquals(oldContentId, dirCache.getEntry("data.txt").getObjectId());
+
+		// Not moved file still in its old place
+		assertNotNull(dirCache.getEntry("file2.txt"));
+	}
+
+	/**
+	 * Rename "folder" to "dir".
+	 *
+	 * @throws Exception
+	 */
+	@Test
+	public void testMoveFolder() throws Exception {
+		TestProject project = initRepoInsideProjectInsideWorkspace();
+		testUtils.addFileToProject(project.getProject(), "folder/file.txt",
+				"some text");
+		testUtils.addFileToProject(project.getProject(), "folder2/file.txt",
+				"some other text");
+		AddToIndexOperation addToIndexOperation = new AddToIndexOperation(
+				new IResource[] {
+						project.getProject().getFile("folder/file.txt"),
+						project.getProject().getFile("folder2/file.txt") });
+		addToIndexOperation.execute(null);
+
+		DirCache dirCache = DirCache.read(repository.getIndexFile(),
+				FS.DETECTED);
+		assertNotNull(dirCache.getEntry("folder/file.txt"));
+		assertNotNull(dirCache.getEntry("folder2/file.txt"));
+		assertNull(dirCache.getEntry("dir/file.txt"));
+		assertFalse(project.getProject().getFile("dir/file.txt").exists());
+		ObjectId oldContentId = dirCache.getEntry("folder/file.txt")
+				.getObjectId();
+		// Modify the content before the move
+		testUtils.changeContentOfFile(project.getProject(), project
+				.getProject().getFile("folder/file.txt"), "other text");
+		project.getProject()
+				.getFolder("folder")
+				.move(project.getProject().getFolder("dir").getFullPath(),
+						false, null);
+
+		dirCache.read();
+		assertTrue(project.getProject().getFile("dir/file.txt").exists());
+		assertNull(dirCache.getEntry("folder/file.txt"));
+		assertNotNull(dirCache.getEntry("dir/file.txt"));
+		// Same content in index as before the move
+		assertEquals(oldContentId, dirCache.getEntry("dir/file.txt")
+				.getObjectId());
+		// Not moved file still there
+		assertNotNull(dirCache.getEntry("folder2/file.txt"));
+	}
+
+	/**
+	 * Rename and move a project in the workspace containing a Git repository.
+	 * <p>
+	 * The repository will be moved with the project.
+	 * Note that there is no way to rename a project in the workspace without
+	 * moving it. See https://bugs.eclipse.org/358828 for a discussion.
+	 *
+	 * @throws Exception
+	 */
+	@Test
+	public void testMoveAndRenameProjectContainingGitRepo() throws Exception {
+		ResourcesPlugin.getWorkspace().getRoot().getProject("Project-1").delete(true, null);
+		ResourcesPlugin.getWorkspace().getRoot().getProject("P2").delete(true, null);
+
+		TestProject project = initRepoInsideProjectInsideWorkspace();
+		testUtils.addFileToProject(project.getProject(), "file.txt",
+				"some text");
+		AddToIndexOperation addToIndexOperation = new AddToIndexOperation(
+				new IResource[] { project.getProject().getFile("file.txt") });
+		addToIndexOperation.execute(null);
+		IProjectDescription description = project.getProject().getDescription();
+		description.setName("P2");
+		registerWorkspaceRelativeTestDir("P2");
+		project.getProject().move(description,
+				IResource.FORCE | IResource.SHALLOW, null);
+		IProject project2 = ResourcesPlugin.getWorkspace().getRoot()
+				.getProject("P2");
+		assertNotNull(RepositoryMapping.getMapping(project2.getProject()));
+		Repository movedRepo = RepositoryMapping.getMapping(project2)
+				.getRepository();
+		assertEquals("P2",
+				movedRepo.getDirectory().getParentFile()
+						.getName());
+		DirCache dc = movedRepo.readDirCache();
+		assertEquals(1, dc.getEntryCount());
+		assertEquals("file.txt", dc.getEntry(0).getPathString());
+
+		assertFalse(ResourcesPlugin.getWorkspace().getRoot().getProject("Project-1").exists());
+	}
+
+	/**
+	 * Rename a project outside the workspace containing a Git repository.
+	 * <p>
+	 * Note the similarity of the code with {@link #testMoveAndRenameProjectContainingGitRepo()}
+	 *
+	 * @throws Exception
+	 */
+	@Test
+	public void testRenameProjectOutsideWorkspaceContainingGitRepo() throws Exception {
+		ResourcesPlugin.getWorkspace().getRoot().getProject("Project-1").delete(true, null);
+		ResourcesPlugin.getWorkspace().getRoot().getProject("P2").delete(true, null);
+		TestProject project = initRepoInsideProjectOutsideWorkspace();
+		testUtils.addFileToProject(project.getProject(), "file.txt",
+				"some text");
+		AddToIndexOperation addToIndexOperation = new AddToIndexOperation(
+				new IResource[] { project.getProject().getFile("file.txt") });
+		addToIndexOperation.execute(null);
+		IProjectDescription description = project.getProject().getDescription();
+		description.setName("P2");
+		project.getProject().move(description,
+				IResource.FORCE | IResource.SHALLOW, null);
+		IProject project2 = ResourcesPlugin.getWorkspace().getRoot()
+				.getProject("P2");
+		assertNotNull(RepositoryMapping.getMapping(project2.getProject()));
+		Repository movedRepo = RepositoryMapping.getMapping(project2)
+				.getRepository();
+		assertEquals("Project-1",
+				movedRepo.getDirectory().getParentFile()
+						.getName());
+		DirCache dc = movedRepo.readDirCache();
+		assertEquals(1, dc.getEntryCount());
+		assertEquals("file.txt", dc.getEntry(0).getPathString());
+
+		assertFalse(ResourcesPlugin.getWorkspace().getRoot().getProject("Project-1").exists());
+	}
+
+	/**
+	 * Move a project outside the workspace containing a Git repository, but do not rename it.
+	 * <p>
+	 * Note the similarity of the code with {@link #testMoveAndRenameProjectContainingGitRepo()}
+	 *
+	 * @throws Exception
+	 */
+	@Test
+	public void testMoveButDoNotRenameProjectOutsideWorkspaceContainingGitRepo() throws Exception {
+		ResourcesPlugin.getWorkspace().getRoot().getProject("Project-1").delete(true, null);
+		ResourcesPlugin.getWorkspace().getRoot().getProject("P2").delete(true, null);
+		TestProject project = initRepoInsideProjectOutsideWorkspace();
+		testUtils.addFileToProject(project.getProject(), "file.txt",
+				"some text");
+		AddToIndexOperation addToIndexOperation = new AddToIndexOperation(
+				new IResource[] { project.getProject().getFile("file.txt") });
+		addToIndexOperation.execute(null);
+		IProjectDescription description = project.getProject().getDescription();
+		description.setLocationURI(URIUtil.toURI(new Path(new File(project.getWorkspaceSupplement(), "P2").getAbsolutePath())));
+		project.getProject().move(description,
+				IResource.FORCE | IResource.SHALLOW, null);
+		IProject project2 = ResourcesPlugin.getWorkspace().getRoot()
+				.getProject("Project-1"); // same name
+		assertNotNull(RepositoryMapping.getMapping(project2.getProject()));
+		Repository movedRepo = RepositoryMapping.getMapping(project2)
+				.getRepository();
+		assertEquals("P2",
+				movedRepo.getDirectory().getParentFile()
+						.getName());
+		DirCache dc = movedRepo.readDirCache();
+		assertEquals(1, dc.getEntryCount());
+		assertEquals("file.txt", dc.getEntry(0).getPathString());
+
+		assertFalse(ResourcesPlugin.getWorkspace().getRoot().getProject("P2").exists());
+	}
+
+
+	@Test
+	public void testMoveProjectWithinGitRepoMoveAtSameTopLevel()
+			throws Exception {
+		dotestMoveProjectWithinRepoWithinWorkspace("", "Project-1", "", "P2", "");
+	}
+
+	@Test
+	public void testMoveProjectWithinGitRepoMoveFromTopOneLevelDown()
+			throws Exception {
+		dotestMoveProjectWithinRepoWithinWorkspace("", "Project-1", "X/", "P2", "");
+	}
+
+	@Test
+	public void testMoveProjectWithinGitRepoMoveFromOneLevelDownToTop()
+			throws Exception {
+		dotestMoveProjectWithinRepoWithinWorkspace("P/", "Project-1", "", "P2", "");
+	}
+
+	@Test
+	public void testMoveProjectWithinGitRepoMoveFromOneLevelDownToSameDepth()
+			throws Exception {
+		dotestMoveProjectWithinRepoWithinWorkspace("P/", "Project-1", "X/", "P2", "");
+	}
+
+	@Test
+	public void testMoveProjectWithinGitRepoMoveFromOneLevelDownOutsideTheRepo()
+			throws Exception {
+		dotestMoveProjectWithinRepoWithinWorkspace("P/", "Project-1", "P/", "P2", "P/");
+	}
+
+	@Test
+	public void testMoveProjectWithinGitOutsideWorkspaceRepoMoveAtSameTopLevel()
+			throws Exception {
+		dotestMoveProjectWithinRepoOutsideWorkspace("", "Project-1", "", "P2", "");
+	}
+
+	@Test
+	public void testMoveProjectWithinGitOutsideWorkspaceRepoMoveFromTopOneLevelDown()
+			throws Exception {
+		dotestMoveProjectWithinRepoOutsideWorkspace("", "Project-1", "X/", "P2", "");
+	}
+
+	@Test
+	public void testMoveProjectWithinGitOutsideWorkspaceRepoMoveFromOneLevelDownToTop()
+			throws Exception {
+		dotestMoveProjectWithinRepoOutsideWorkspace("P/", "Project-1", "", "P2", "");
+	}
+
+	@Test
+	public void testMoveProjectWithinGitOutsideWorkspaceRepoMoveFromOneLevelDownToSameDepth()
+			throws Exception {
+		dotestMoveProjectWithinRepoOutsideWorkspace("P/", "Project-1", "X/", "P2", "");
+	}
+
+	@Test
+	public void testMoveProjectWithinGitOutsideWorkspaceRepoMoveFromOneLevelDownOutsideTheRepo()
+			throws Exception {
+		dotestMoveProjectWithinRepoOutsideWorkspace("P/", "Project-1", "P/", "P2", "P/");
+	}
+
+
+	@Test
+	public void testMoveProjectWithinGitRepoMoveFromLevelZeroDownOne()
+			throws Exception {
+		// In this case we'd expect the project to move, but not the repository
+		// TODO: Eclipse cannot do this even without the Git plugin either,
+		// TODO: See Bug 307140)
+		try {
+			dotestMoveProjectWithinRepoWithinWorkspace("P/", "Project-1",
+					"P/Project-1/", "P2", "P/Project-1/");
+			if (!"true".equals(System.getProperty("egit.assume_307140_fixed")))
+				fail("ResourceException expected, core functionality dangerously broken and therefore forbidden");
+		} catch (CoreException e) {
+			if ("true".equals(System.getProperty("egit.assume_307140_fixed")))
+				throw e;
+		}
+	}
+
+	@Test
+	public void testMoveFileWithConflictsShouldBeCanceled() throws Exception {
+		TestProject project = initRepoInsideProjectInsideWorkspace();
+		String filePath = "file.txt";
+		IFile file = testUtils.addFileToProject(project.getProject(), filePath, "some text");
+
+		Repository repo = testRepository.getRepository();
+		DirCache index = repo.lockDirCache();
+		DirCacheBuilder builder = index.builder();
+		addUnmergedEntry(filePath, builder);
+		builder.commit();
+
+		try {
+			file.move(new Path("destination.txt"), false, null);
+			fail("Expected move of file with conflicts to fail.");
+		} catch (CoreException e) {
+			IStatus status = e.getStatus();
+			assertNotNull(status);
+			assertEquals(IStatus.WARNING, status.getSeverity());
+		}
+
+		assertTrue("File should still exist at old location", file.exists());
+		DirCache indexAfter = repo.readDirCache();
+		DirCacheEntry entry = indexAfter.getEntry(filePath);
+		assertEquals("Expected entry to still be in non-zero (conflict) stage",
+				DirCacheEntry.STAGE_1, entry.getStage());
+	}
+
+	@Test
+	public void testMoveFolderWithFileWithConflictsShouldBeCanceled() throws Exception {
+		TestProject project = initRepoInsideProjectInsideWorkspace();
+		String filePath = "folder/file.txt";
+		IFile file = testUtils.addFileToProject(project.getProject(), filePath, "some text");
+
+		Repository repo = testRepository.getRepository();
+		DirCache index = repo.lockDirCache();
+		DirCacheBuilder builder = index.builder();
+		addUnmergedEntry(filePath, builder);
+		builder.commit();
+
+		try {
+			project.getProject()
+					.getFolder("folder")
+					.move(project.getProject().getFolder("newfolder")
+							.getFullPath(), false, null);
+			fail("Expected move of folder with file with conflicts to fail.");
+		} catch (CoreException e) {
+			IStatus status = e.getStatus();
+			assertNotNull(status);
+			assertEquals(IStatus.WARNING, status.getSeverity());
+		}
+
+		assertTrue("File should still exist at old location", file.exists());
+		DirCache indexAfter = repo.readDirCache();
+		DirCacheEntry entry = indexAfter.getEntry(filePath);
+		assertEquals("Expected entry to still be in non-zero (conflict) stage",
+				DirCacheEntry.STAGE_1, entry.getStage());
+	}
+
+	private static void addUnmergedEntry(String filePath, DirCacheBuilder builder) {
+		DirCacheEntry stage1 = new DirCacheEntry(filePath, DirCacheEntry.STAGE_1);
+		DirCacheEntry stage2 = new DirCacheEntry(filePath, DirCacheEntry.STAGE_2);
+		DirCacheEntry stage3 = new DirCacheEntry(filePath, DirCacheEntry.STAGE_3);
+		stage1.setFileMode(FileMode.REGULAR_FILE);
+		stage2.setFileMode(FileMode.REGULAR_FILE);
+		stage3.setFileMode(FileMode.REGULAR_FILE);
+		builder.add(stage1);
+		builder.add(stage2);
+		builder.add(stage3);
+	}
+
+	private void dotestMoveProjectWithinRepoWithinWorkspace(String srcParent,
+			String srcProjectName, String dstParent, String dstProjecName,
+			String gitDir) throws CoreException, IOException, Exception,
+			CorruptObjectException {
+		dotestMoveProjectWithinRepo(srcParent, srcProjectName, dstParent, dstProjecName, gitDir, true);
+	}
+
+	private void dotestMoveProjectWithinRepoOutsideWorkspace(String srcParent,
+			String srcProjectName, String dstParent, String dstProjecName,
+			String gitDir) throws CoreException, IOException, Exception,
+			CorruptObjectException {
+		dotestMoveProjectWithinRepo(srcParent, srcProjectName, dstParent, dstProjecName, gitDir, false);
+	}
+
+	private void dotestMoveProjectWithinRepo(String srcParent,
+			String srcProjectName, String dstParent, String dstProjecName,
+			String gitDir, boolean sourceInsideWs) throws IOException, CoreException {
+		String gdRelativeSrcParent = srcParent + srcProjectName + "/";
+		if (gdRelativeSrcParent.startsWith(gitDir))
+			gdRelativeSrcParent = gdRelativeSrcParent
+					.substring(gitDir.length());
+		String gdRelativeDstParent = dstParent + dstProjecName + "/";
+		if (gdRelativeDstParent.startsWith(gitDir))
+			gdRelativeDstParent = gdRelativeDstParent
+					.substring(gitDir.length());
+
+		registerWorkspaceRelativeTestDirProject(srcParent, srcProjectName);
+		registerWorkspaceRelativeTestDirProject(dstParent, dstProjecName);
+
+		// Old cruft may be laying around
+		TestProject project = initRepoAboveProject(srcParent, gitDir, sourceInsideWs);
+		IProject project0 = project.getProject().getWorkspace().getRoot()
+				.getProject(dstProjecName);
+		project0.delete(true, null);
+
+		testUtils.addFileToProject(project.getProject(), "file.txt",
+				"some text");
+		AddToIndexOperation addToIndexOperation = new AddToIndexOperation(
+				new IResource[] { project.getProject().getFile("file.txt") });
+		addToIndexOperation.execute(null);
+
+		// Check condition before move
+		DirCache dirCache = DirCache.read(repository.getIndexFile(),
+				FS.DETECTED);
+		assertNotNull(dirCache.getEntry(gdRelativeSrcParent + "file.txt"));
+		ObjectId oldContentId = dirCache.getEntry(
+				gdRelativeSrcParent + "file.txt").getObjectId();
+
+		// Modify the content before the move, we want to see the staged content
+		// as it was before the move in the index
+		testUtils.changeContentOfFile(project.getProject(), project
+				.getProject().getFile("file.txt"), "other text");
+		IProjectDescription description = project.getProject().getDescription();
+		description.setName(dstProjecName);
+		if (sourceInsideWs)
+			if (dstParent.length() > 0)
+				description.setLocationURI(URIUtil.toURI(project.getProject()
+						.getWorkspace().getRoot().getLocation()
+						.append(dstParent + dstProjecName)));
+			else
+				description.setLocationURI(null);
+		else
+			description.setLocationURI(URIUtil.toURI(new Path(workspaceSupplement + "/" + dstParent + "/" + dstProjecName)));
+		project.getProject().move(description,
+				IResource.FORCE | IResource.SHALLOW, null);
+		IProject project2 = project.getProject().getWorkspace().getRoot()
+				.getProject(dstProjecName);
+		assertTrue(project2.exists());
+		assertNotNull(RepositoryMapping.getMapping(project2));
+
+		// Check that our file exists on disk has a new location in the index
+		dirCache.read();
+		assertTrue(project2.getFile("file.txt").exists());
+		assertNotNull(dirCache.getEntry(gdRelativeDstParent + "file.txt"));
+
+		// Same content in index as before the move, i.e. not same as on disk
+		assertEquals(oldContentId,
+				dirCache.getEntry(gdRelativeDstParent + "file.txt")
+						.getObjectId());
+	}
+
+
+	private void registerWorkspaceRelativeTestDirProject(String parent, String projName) {
+		if ((parent != null) && !parent.equals(""))
+			registerWorkspaceRelativeTestDir(parent);
+		else
+			registerWorkspaceRelativeTestDir(projName);
+	}
+
+	private void registerWorkspaceRelativeTestDir(String relativeDir) {
+		if ((relativeDir != null) && !relativeDir.equals("")) {
+			File d = new File(workspace, relativeDir);
+			testDirs.add(d);
+		}
+	}
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/AddOperationTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/AddOperationTest.java
new file mode 100644
index 0000000..9de10ae
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/AddOperationTest.java
@@ -0,0 +1,162 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Stefan Lay <stefan.lay@sap.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.egit.core.internal.op.AddToIndexOperation;
+import org.eclipse.egit.core.internal.test.GitTestCase;
+import org.eclipse.egit.core.internal.test.TestRepository;
+import org.eclipse.jgit.lib.Constants;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class AddOperationTest extends GitTestCase {
+
+	private List<IResource> resources = new ArrayList<IResource>();
+
+	TestRepository testRepository;
+
+	@Before
+	public void setUp() throws Exception {
+		super.setUp();
+		gitDir = new File(project.getProject()
+				.getLocationURI().getPath(), Constants.DOT_GIT);
+		testRepository = new TestRepository(gitDir);
+		testRepository.connect(project.getProject());
+	}
+
+	@After
+	public void tearDown() throws Exception {
+		testRepository.dispose();
+		super.tearDown();
+	}
+
+	@Test
+	public void testTrackFile() throws Exception {
+		IFile file1 = testUtils.addFileToProject(project.getProject(), "a.txt",
+				"some text");
+
+		assertFalse(testRepository.inIndex(file1.getLocation()
+				.toPortableString()));
+
+		resources.add(file1);
+		new AddToIndexOperation(resources).execute(null);
+
+		assertTrue(testRepository.inIndex(file1.getLocation()
+				.toPortableString()));
+	}
+
+	@Test
+	public void testTrackFilesInFolder() throws Exception {
+		IFile file1 = testUtils.addFileToProject(project.getProject(),
+				"sub/a.txt", "some text");
+		IFile file2 = testUtils.addFileToProject(project.getProject(),
+				"sub/b.txt", "some text");
+
+		assertFalse(testRepository.inIndex(file1.getLocation()
+				.toPortableString()));
+		assertFalse(testRepository.inIndex(file2.getLocation()
+				.toPortableString()));
+
+		resources.add(project.getProject().getFolder("sub"));
+		new AddToIndexOperation(resources).execute(null);
+
+		assertTrue(testRepository.inIndex(file1.getLocation()
+				.toPortableString()));
+		assertTrue(testRepository.inIndex(file2.getLocation()
+				.toPortableString()));
+	}
+
+	@Test
+	public void testAddFile() throws Exception {
+		IFile file1 = testUtils.addFileToProject(project.getProject(), "a.txt",
+				"some text");
+
+		resources.add(file1);
+		new AddToIndexOperation(resources).execute(null);
+
+		testRepository.commit("first commit");
+
+		assertEquals(file1.getLocalTimeStamp(),
+				testRepository.lastModifiedInIndex(file1.getLocation()
+						.toPortableString()));
+
+		Thread.sleep(1000);
+		file1.setContents(
+				new ByteArrayInputStream("other text".getBytes(project.project
+						.getDefaultCharset())), 0, null);
+
+		assertFalse(file1.getLocalTimeStamp() == testRepository
+				.lastModifiedInIndex(file1.getLocation().toPortableString()));
+
+		new AddToIndexOperation(resources).execute(null);
+
+		assertTrue(testRepository.inIndex(file1.getLocation()
+				.toPortableString()));
+		// does not work yet due to the racy git problem: DirCache.writeTo
+		// smudges the
+		// timestamp of an added file
+		 assertEquals(file1.getLocalTimeStamp() / 10,
+				 testRepository.lastModifiedInIndex(file1.getLocation().toPortableString()) / 10);
+	}
+
+	@Test
+	public void testAddFilesInFolder() throws Exception {
+		IFile file1 = testUtils.addFileToProject(project.getProject(),
+				"sub/a.txt", "some text");
+		IFile file2 = testUtils.addFileToProject(project.getProject(),
+				"sub/b.txt", "some text");
+
+		resources.add(project.getProject().getFolder("sub"));
+		new AddToIndexOperation(resources).execute(null);
+
+		testRepository.commit("first commit");
+
+		assertEquals(file1.getLocalTimeStamp(),
+				testRepository.lastModifiedInIndex(file1.getLocation()
+						.toPortableString()));
+
+		Thread.sleep(1000);
+
+		file1.setContents(
+				new ByteArrayInputStream("other text".getBytes(project.project
+						.getDefaultCharset())), 0, null);
+		file2.setContents(
+				new ByteArrayInputStream("other text".getBytes(project.project
+						.getDefaultCharset())), 0, null);
+
+		assertFalse(file1.getLocalTimeStamp() == testRepository
+				.lastModifiedInIndex(file1.getLocation().toPortableString()));
+		assertFalse(file2.getLocalTimeStamp() == testRepository
+				.lastModifiedInIndex(file1.getLocation().toPortableString()));
+
+		new AddToIndexOperation(resources).execute(null);
+
+		assertTrue(testRepository.inIndex(file1.getLocation()
+				.toPortableString()));
+		assertTrue(testRepository.inIndex(file2.getLocation()
+				.toPortableString()));
+
+		 assertEquals(file1.getLocalTimeStamp() / 10,
+				 testRepository.lastModifiedInIndex(file1.getLocation().toPortableString()) / 10);
+		 assertEquals(file2.getLocalTimeStamp() / 10,
+				 testRepository.lastModifiedInIndex(file2.getLocation().toPortableString()) / 10);
+	}
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/BranchOperationTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/BranchOperationTest.java
new file mode 100644
index 0000000..8fea063
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/BranchOperationTest.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Jens Baumgart <jens.baumgart@sap.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+
+import org.eclipse.egit.core.internal.op.BranchOperation;
+import org.eclipse.egit.core.internal.test.GitTestCase;
+import org.eclipse.egit.core.internal.test.TestRepository;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.Repository;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class BranchOperationTest extends GitTestCase{
+
+	private static final String TEST = Constants.R_HEADS + "test";
+	private static final String MASTER = Constants.R_HEADS + "master";
+	TestRepository testRepository;
+	Repository repository;
+
+	@Before
+	public void setUp() throws Exception {
+		super.setUp();
+		testRepository = new TestRepository(gitDir);
+		repository = testRepository.getRepository();
+	}
+
+	@After
+	public void tearDown() throws Exception {
+		testRepository.dispose();
+		repository = null;
+		super.tearDown();
+	}
+
+	@Test
+	public void testBranchOperation() throws Exception {
+		// create first commit containing a dummy file
+		testRepository.createInitialCommit("testBranchOperation\n\nfirst commit\n");
+		// create branch test and switch to branch test
+		testRepository.createBranch(MASTER, TEST);
+		new BranchOperation(repository, TEST).execute(null);
+		assertTrue(repository.getFullBranch().equals(TEST));
+		// add .project to version control and commit
+		String path = project.getProject().getLocation().append(".project").toOSString();
+		File file = new File(path);
+		testRepository.track(file);
+		testRepository.commit("Add .project file");
+		// switch back to master branch
+		// .project must disappear, related Eclipse project must be deleted
+		new BranchOperation(repository, MASTER).execute(null);
+		assertFalse(file.exists());
+		assertFalse(project.getProject().exists());
+		// switch back to master test
+		// .project must reappear
+		new BranchOperation(repository, TEST).execute(null);
+		assertTrue(file.exists());
+	}
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/CloneOperationTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/CloneOperationTest.java
new file mode 100644
index 0000000..f3c6e0c
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/CloneOperationTest.java
@@ -0,0 +1,160 @@
+/*******************************************************************************
+ * Copyright (C) 2011, Stefan Lay <stefan.lay@sap.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.egit.core.internal.op;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.egit.core.internal.op.CloneOperation;
+import org.eclipse.egit.core.internal.op.ConfigureFetchAfterCloneTask;
+import org.eclipse.egit.core.internal.op.ConfigurePushAfterCloneTask;
+import org.eclipse.egit.core.internal.op.CloneOperation.PostCloneTask;
+import org.eclipse.egit.core.internal.test.DualRepositoryTestCase;
+import org.eclipse.egit.core.internal.test.TestRepository;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.lib.ConfigConstants;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.internal.storage.file.FileRepository;
+import org.eclipse.jgit.transport.URIish;
+import org.eclipse.jgit.util.FileUtils;
+import org.junit.Before;
+import org.junit.Test;
+
+public class CloneOperationTest extends DualRepositoryTestCase {
+
+	File workdir;
+
+	File workdir2;
+
+	@Before
+	public void setUp() throws Exception {
+		workdir = testUtils.createTempDir("Repository1");
+		workdir2 = testUtils.createTempDir("Repository2");
+
+		repository1 = new TestRepository(new File(workdir, Constants.DOT_GIT));
+
+		File file = new File(workdir, "file1.txt");
+		FileUtils.createNewFile(file);
+		Git git = new Git(repository1.getRepository());
+		git.add().addFilepattern("file1.txt").call();
+
+		git.commit().setMessage("first commit").call();
+	}
+
+	@Test
+	public void testClone() throws Exception {
+		URIish uri = new URIish("file:///"
+				+ repository1.getRepository().getDirectory().toString());
+		CloneOperation clop = new CloneOperation(uri, true, null, workdir2,
+				"refs/heads/master", "origin", 0);
+		clop.run(null);
+
+		Repository clonedRepo = new FileRepository(new File(workdir2,
+				Constants.DOT_GIT));
+		assertEquals(
+				"",
+				uri.toString(),
+				clonedRepo.getConfig().getString(
+						ConfigConstants.CONFIG_REMOTE_SECTION, "origin", "url"));
+		assertEquals(
+				"",
+				"+refs/heads/*:refs/remotes/origin/*",
+				clonedRepo.getConfig().getString(
+						ConfigConstants.CONFIG_REMOTE_SECTION, "origin",
+						"fetch"));
+
+		File file = new File(workdir2, "file1.txt");
+		assertTrue(file.exists());
+	}
+
+	@Test
+	public void testSimplePostCloneTask() throws Exception {
+		URIish uri = new URIish("file:///"
+				+ repository1.getRepository().getDirectory().toString());
+		CloneOperation clop = new CloneOperation(uri, true, null, workdir2,
+				"refs/heads/master", "origin", 0);
+
+		final File[] repoDir = new File[1];
+		clop.addPostCloneTask(new PostCloneTask() {
+
+			public void execute(Repository repository, IProgressMonitor monitor)
+					throws CoreException {
+				repoDir[0] = repository.getDirectory();
+
+			}
+		});
+		clop.run(null);
+		File newRepoDir = new File(workdir2, Constants.DOT_GIT);
+		assertEquals(newRepoDir, repoDir[0]);
+	}
+
+	@Test
+	public void testConfigurePushAfterCloneTask() throws Exception {
+		URIish uri = new URIish("file:///"
+				+ repository1.getRepository().getDirectory().toString());
+		CloneOperation clop = new CloneOperation(uri, true, null, workdir2,
+				"refs/heads/master", "origin", 0);
+
+		clop.addPostCloneTask(new ConfigurePushAfterCloneTask("origin",
+				"HEAD:refs/for/master", new URIish("file:///pushtarget")));
+		clop.run(null);
+		Repository clonedRepo = new FileRepository(new File(workdir2,
+				Constants.DOT_GIT));
+		assertEquals(
+				"",
+				"HEAD:refs/for/master",
+				clonedRepo.getConfig()
+				.getString(ConfigConstants.CONFIG_REMOTE_SECTION,
+						"origin", "push"));
+		assertEquals(
+				"",
+				"file:///pushtarget",
+				clonedRepo.getConfig().getString(
+						ConfigConstants.CONFIG_REMOTE_SECTION, "origin",
+						"pushurl"));
+	}
+
+	@Test
+	public void testConfigureFetchAfterCloneTask() throws Exception {
+		createNoteInOrigin();
+
+		URIish uri = new URIish("file:///"
+				+ repository1.getRepository().getDirectory().toString());
+		CloneOperation clop = new CloneOperation(uri, true, null, workdir2,
+				"refs/heads/master", "origin", 0);
+
+		clop.addPostCloneTask(new ConfigureFetchAfterCloneTask("origin",
+				"refs/notes/review:refs/notes/review"));
+		clop.run(null);
+		Repository clonedRepo = new FileRepository(new File(workdir2,
+				Constants.DOT_GIT));
+		assertTrue(
+				clonedRepo.getConfig()
+				.getStringList(ConfigConstants.CONFIG_REMOTE_SECTION,
+						"origin", "fetch")[1].equals("refs/notes/review:refs/notes/review"));
+		Git clonedGit = new Git(clonedRepo);
+		assertEquals(1, clonedGit.notesList().setNotesRef("refs/notes/review").call().size());
+	}
+
+	protected void createNoteInOrigin() throws GitAPIException {
+		Git git = new Git(repository1.getRepository());
+		git.add().addFilepattern("file.txt").call();
+		RevCommit commit = git.commit().setMessage("Initial commit").call();
+		git.notesAdd().setNotesRef("refs/notes/review").setObjectId(commit).setMessage("text").call();
+	}
+
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/CommitOperationTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/CommitOperationTest.java
new file mode 100644
index 0000000..a209ca0
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/CommitOperationTest.java
@@ -0,0 +1,318 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Stefan Lay <stefan.lay@sap.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.egit.core.internal.op;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.egit.core.internal.op.AddToIndexOperation;
+import org.eclipse.egit.core.internal.op.CommitOperation;
+import org.eclipse.egit.core.internal.test.GitTestCase;
+import org.eclipse.egit.core.internal.test.TestRepository;
+import org.eclipse.egit.core.internal.test.TestUtils;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.treewalk.TreeWalk;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class CommitOperationTest extends GitTestCase {
+
+	private static List<IFile> EMPTY_FILE_LIST = new ArrayList<IFile>();
+
+	private List<IResource> resources = new ArrayList<IResource>();
+
+	TestRepository testRepository;
+
+	Repository repository;
+
+	@Before
+	public void setUp() throws Exception {
+		super.setUp();
+		gitDir = new File(project.getProject()
+				.getLocationURI().getPath(), Constants.DOT_GIT);
+		testRepository = new TestRepository(gitDir);
+		repository = testRepository.getRepository();
+		testRepository.connect(project.getProject());
+	}
+
+	@After
+	public void tearDown() throws Exception {
+		testRepository.dispose();
+		repository = null;
+		super.tearDown();
+	}
+
+	@Test
+	public void testCommitAddedToIndexDeletedInWorkspace() throws Exception {
+		testUtils.addFileToProject(project.getProject(), "foo/a.txt", "some text");
+		resources.add(project.getProject().getFolder("foo"));
+		new AddToIndexOperation(resources).execute(null);
+		CommitOperation commitOperation = new CommitOperation(null, null, TestUtils.AUTHOR, TestUtils.COMMITTER, "first commit");
+		commitOperation.setCommitAll(true);
+		commitOperation.setRepository(repository);
+		commitOperation.execute(null);
+
+		testUtils.addFileToProject(project.getProject(), "zar/b.txt", "some text");
+		resources.add(project.getProject().getFolder("zar"));
+		new AddToIndexOperation(resources).execute(null);
+		IFile zarFile = project.getProject().getFile("zar/b.txt");
+		IPath zarFilePath = zarFile.getLocation();
+		// delete file and refresh. Deleting using the resource would trigger
+		// GitMoveDeleteHook which removes the file from the index
+		assertTrue("could not delete file " + zarFilePath.toOSString(),
+				zarFilePath.toFile().delete());
+		zarFile.refreshLocal(0, null);
+
+		assertFalse(project.getProject().getFile("zar/b.txt").exists());
+
+		IFile[] filesToCommit = new IFile[] { project.getProject().getFile("zar/b.txt") };
+		commitOperation = new CommitOperation(filesToCommit, null, TestUtils.AUTHOR, TestUtils.COMMITTER, "first commit");
+		commitOperation.setRepository(repository);
+		try {
+			commitOperation.execute(null);
+			// TODO this is very ugly. CommitCommand should be extended
+			// not to throw an JGitInternalException in case of an empty
+			// commit
+			fail("expected CoreException");
+		} catch (CoreException e) {
+			assertEquals("No changes", e.getCause().getMessage());
+		}
+
+		TreeWalk treeWalk = new TreeWalk(repository);
+		treeWalk.addTree(repository.resolve("HEAD^{tree}"));
+		assertTrue(treeWalk.next());
+		assertEquals("foo", treeWalk.getPathString());
+		treeWalk.enterSubtree();
+		assertTrue(treeWalk.next());
+		assertEquals("foo/a.txt", treeWalk.getPathString());
+		assertFalse(treeWalk.next());
+	}
+
+	@Test
+	public void testCommitAll() throws Exception {
+		IFile file1 = testUtils.addFileToProject(project.getProject(),
+				"sub/a.txt", "some text");
+		testUtils.addFileToProject(project.getProject(),
+				"sub/b.txt", "some text");
+
+		resources.add(project.getProject().getFolder("sub"));
+		new AddToIndexOperation(resources).execute(null);
+		CommitOperation commitOperation = new CommitOperation(null, null, TestUtils.AUTHOR,
+				TestUtils.COMMITTER, "first commit");
+		commitOperation.setCommitAll(true);
+		commitOperation.setRepository(repository);
+		commitOperation.execute(null);
+
+		Git git = new Git(repository);
+		Iterator<RevCommit> commits = git.log().call().iterator();
+		RevCommit firstCommit = commits.next();
+		assertTrue(firstCommit.getCommitTime() > 0);
+
+		assertEquals("first commit", firstCommit.getFullMessage());
+
+		testUtils.changeContentOfFile(project.getProject(), file1, "changed text");
+
+		commitOperation = new CommitOperation(null, null, TestUtils.AUTHOR,
+				TestUtils.COMMITTER, "second commit");
+		commitOperation.setCommitAll(true);
+		commitOperation.setRepository(repository);
+		commitOperation.execute(null);
+
+		git = new Git(repository);
+		commits = git.log().call().iterator();
+		RevCommit secondCommit = commits.next();
+		assertTrue(secondCommit.getCommitTime() > 0);
+
+		assertEquals("second commit", secondCommit.getFullMessage());
+		secondCommit.getParent(0).equals(firstCommit);
+		assertEquals("The Author", secondCommit.getAuthorIdent().getName());
+		assertEquals("The.author@some.com", secondCommit.getAuthorIdent().getEmailAddress());
+		assertEquals("The Commiter", secondCommit.getCommitterIdent().getName());
+		assertEquals("The.committer@some.com", secondCommit.getCommitterIdent().getEmailAddress());
+	}
+
+	@Test
+	public void testCommitEmptiedTree() throws Exception {
+		// Set up a directory structure
+		testUtils.addFileToProject(project.getProject(),
+				"sub1/a.txt", "some text");
+		testUtils.addFileToProject(project.getProject(),
+				"sub2/b.txt", "some text");
+		resources.add(project.getProject().getFolder("sub1"));
+		resources.add(project.getProject().getFolder("sub2"));
+		new AddToIndexOperation(resources).execute(null);
+		CommitOperation commitOperation = new CommitOperation(null, null, TestUtils.AUTHOR,
+				TestUtils.COMMITTER, "first commit");
+		commitOperation.setCommitAll(true);
+		commitOperation.setRepository(repository);
+		commitOperation.execute(null);
+
+		Git git = new Git(repository);
+		Iterator<RevCommit> commits = git.log().call().iterator();
+		RevCommit secondCommit = commits.next();
+		TreeWalk treeWalk = new TreeWalk(repository);
+		treeWalk.addTree(secondCommit.getTree().getId());
+		treeWalk.setRecursive(true);
+		treeWalk.setPostOrderTraversal(true);
+		assertTrue(treeWalk.next());
+		assertEquals("sub1/a.txt", treeWalk.getPathString());
+		assertTrue(treeWalk.next());
+		assertEquals("sub1", treeWalk.getPathString());
+		assertTrue(treeWalk.next());
+		assertEquals("sub2/b.txt", treeWalk.getPathString());
+		assertTrue(treeWalk.next());
+		assertEquals("sub2", treeWalk.getPathString());
+		assertFalse(treeWalk.next());
+
+		project.getProject().getFolder("sub2").delete(IResource.FORCE, null);
+		IFile[] filesToCommit = { project.getProject().getFile("sub2/b.txt") };
+		ArrayList<IFile> notIndexed = new ArrayList<IFile>();
+		notIndexed.add(filesToCommit[0]);
+		ArrayList<IFile> notTracked = new ArrayList<IFile>();
+		commitOperation = new CommitOperation(filesToCommit, notTracked, TestUtils.AUTHOR, TestUtils.COMMITTER, "second commit");
+		commitOperation.setCommitAll(false);
+		commitOperation.execute(null);
+
+		git = new Git(repository);
+		commits = git.log().call().iterator();
+		secondCommit = commits.next();
+		treeWalk = new TreeWalk(repository);
+		treeWalk.addTree(secondCommit.getTree().getId());
+		treeWalk.setRecursive(true);
+		treeWalk.setPostOrderTraversal(true);
+		assertTrue(treeWalk.next());
+		assertEquals("sub1/a.txt", treeWalk.getPathString());
+		assertTrue(treeWalk.next());
+		assertEquals("sub1", treeWalk.getPathString());
+		assertFalse(treeWalk.next());
+	}
+
+	@Test
+	public void testCommitUntracked() throws Exception {
+		IFile fileA = testUtils.addFileToProject(project.getProject(),
+				"foo/a.txt", "some text");
+		IFile fileB = testUtils.addFileToProject(project.getProject(),
+				"foo/b.txt", "some text");
+		testUtils.addFileToProject(project.getProject(), "foo/c.txt",
+				"some text");
+		IFile[] filesToCommit = { fileA, fileB };
+		CommitOperation commitOperation = new CommitOperation(filesToCommit,
+				Arrays.asList(filesToCommit), TestUtils.AUTHOR,
+				TestUtils.COMMITTER, "first commit");
+		commitOperation.execute(null);
+		testUtils.assertRepositoryContainsFiles(repository, getRepoRelativePaths(filesToCommit));
+	}
+
+	private String[] getRepoRelativePaths(IFile[] files) {
+		ArrayList<String> result = new ArrayList<String>();
+		for (IFile file:files)
+			result.add(file.getProjectRelativePath().toString());
+		return result.toArray(new String[result.size()]);
+	}
+
+	@Test
+	public void testCommitStaged() throws Exception {
+		IFile fileA = testUtils.addFileToProject(project.getProject(),
+				"foo/a.txt", "some text");
+		IFile fileB = testUtils.addFileToProject(project.getProject(),
+				"foo/b.txt", "some text");
+		IFile[] filesToCommit = { fileA, fileB };
+		CommitOperation commitOperation = new CommitOperation(filesToCommit,
+				Arrays.asList(filesToCommit), TestUtils.AUTHOR,
+				TestUtils.COMMITTER, "first commit");
+		commitOperation.execute(null);
+		testUtils.changeContentOfFile(project.getProject(), fileA,
+				"new content of A");
+		testUtils.changeContentOfFile(project.getProject(), fileB,
+				"new content of B");
+		resources.add(fileA);
+		resources.add(fileB);
+		new AddToIndexOperation(resources).execute(null);
+		commitOperation = new CommitOperation(filesToCommit, EMPTY_FILE_LIST,
+				TestUtils.AUTHOR, TestUtils.COMMITTER, "second commit");
+		commitOperation.execute(null);
+
+		testUtils.assertRepositoryContainsFilesWithContent(repository,
+				"foo/a.txt", "new content of A", "foo/b.txt",
+				"new content of B");
+	}
+
+	@Test
+	public void testCommitIndexSubset() throws Exception {
+		IFile fileA = testUtils.addFileToProject(project.getProject(),
+				"foo/a.txt", "some text");
+		IFile fileB = testUtils.addFileToProject(project.getProject(),
+				"foo/b.txt", "some text");
+		IFile[] filesToCommit = { fileA, fileB };
+		CommitOperation commitOperation = new CommitOperation(filesToCommit,
+				Arrays.asList(filesToCommit), TestUtils.AUTHOR,
+				TestUtils.COMMITTER, "first commit");
+		commitOperation.execute(null);
+		testUtils.changeContentOfFile(project.getProject(), fileA,
+				"new content of A");
+		testUtils.changeContentOfFile(project.getProject(), fileB,
+				"new content of B");
+		resources.add(fileA);
+		resources.add(fileB);
+		new AddToIndexOperation(resources).execute(null);
+		IFile[] filesToCommit2 = { fileA };
+		commitOperation = new CommitOperation(filesToCommit2, EMPTY_FILE_LIST,
+				TestUtils.AUTHOR, TestUtils.COMMITTER, "second commit");
+		commitOperation.execute(null);
+
+		testUtils.assertRepositoryContainsFilesWithContent(repository,
+				"foo/a.txt", "new content of A", "foo/b.txt", "some text");
+	}
+
+	@Test
+	public void testCommitWithStaging() throws Exception {
+		IFile fileA = testUtils.addFileToProject(project.getProject(),
+				"foo/a.txt", "some text");
+		IFile fileB = testUtils.addFileToProject(project.getProject(),
+				"foo/b.txt", "some text");
+		IFile[] filesToCommit = { fileA, fileB };
+		CommitOperation commitOperation = new CommitOperation(filesToCommit,
+				Arrays.asList(filesToCommit), TestUtils.AUTHOR,
+				TestUtils.COMMITTER, "first commit");
+		commitOperation.execute(null);
+
+		testUtils.changeContentOfFile(project.getProject(), fileA,
+				"new content of A");
+		testUtils.changeContentOfFile(project.getProject(), fileB,
+				"new content of B");
+		resources.add(fileA);
+		resources.add(fileB);
+		commitOperation = new CommitOperation(filesToCommit,
+				EMPTY_FILE_LIST, TestUtils.AUTHOR,
+				TestUtils.COMMITTER, "first commit");
+		commitOperation.execute(null);
+
+		testUtils.assertRepositoryContainsFilesWithContent(repository,
+				"foo/a.txt", "new content of A", "foo/b.txt",
+				"new content of B");
+	}
+
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/ConnectProviderOperationTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/ConnectProviderOperationTest.java
new file mode 100644
index 0000000..b823d17
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/ConnectProviderOperationTest.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (C) 2007, Robin Rosenberg <robin.rosenberg@dewire.com>
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
+ * Copyright (C) 2013, Matthias Sohn <matthias.sohn@sap.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+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.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.GitCorePreferences;
+import org.eclipse.egit.core.internal.JobFamilies;
+import org.eclipse.egit.core.internal.RepositoryUtil;
+import org.eclipse.egit.core.internal.op.ConnectProviderOperation;
+import org.eclipse.egit.core.internal.test.GitTestCase;
+import org.eclipse.egit.core.internal.test.TestRepository;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.internal.storage.file.FileRepository;
+import org.eclipse.team.core.RepositoryProvider;
+import org.junit.Test;
+
+public class ConnectProviderOperationTest extends GitTestCase {
+
+	@Test
+	public void testNoRepository() throws CoreException {
+
+		ConnectProviderOperation operation = new ConnectProviderOperation(
+				project.getProject(), new File("../..", Constants.DOT_GIT));
+		operation.execute(null);
+
+		assertFalse(RepositoryProvider.isShared(project.getProject()));
+		assertFalse(gitDir.exists());
+	}
+
+	@Test
+	public void testNewRepository() throws CoreException, IOException {
+
+		Repository repository = new FileRepository(gitDir);
+		repository.create();
+		repository.close();
+		ConnectProviderOperation operation = new ConnectProviderOperation(
+				project.getProject(), gitDir);
+		operation.execute(null);
+
+		assertTrue(RepositoryProvider.isShared(project.getProject()));
+
+		assertTrue(gitDir.exists());
+	}
+
+	@Test
+	public void testAutoIgnoresDerivedFolder() throws Exception {
+		// enable auto-ignore
+		IEclipsePreferences p = InstanceScope.INSTANCE.getNode(Activator
+				.getPluginId());
+		p.putBoolean(GitCorePreferences.core_autoIgnoreDerivedResources, true);
+		Repository repository = new FileRepository(gitDir);
+		repository.create();
+		repository.close();
+		project.setBinFolderDerived();
+		ConnectProviderOperation operation = new ConnectProviderOperation(
+				project.getProject(), gitDir);
+		operation.execute(null);
+
+		assertTrue(RepositoryProvider.isShared(project.getProject()));
+		Job.getJobManager().join(JobFamilies.AUTO_IGNORE, null);
+
+		IPath binPath = project.getProject().getLocation().append("bin");
+		assertTrue(RepositoryUtil.isIgnored(binPath));
+		assertTrue(gitDir.exists());
+		p.putBoolean(GitCorePreferences.core_autoIgnoreDerivedResources, false);
+	}
+
+	@Test
+	public void testNewUnsharedFile() throws CoreException, Exception {
+
+		project.createSourceFolder();
+		IFile fileA = project.getProject().getFolder("src").getFile("A.java");
+		String srcA = "class A {\n" + "}\n";
+		fileA.create(new ByteArrayInputStream(srcA.getBytes("UTF-8")), false,
+				null);
+
+		TestRepository thisGit = new TestRepository(gitDir);
+
+		File committable = new File(fileA.getLocationURI());
+
+		thisGit.addAndCommit(project.project, committable,
+				"testNewUnsharedFile\n\nJunit tests\n");
+
+		assertNull(RepositoryProvider.getProvider(project.getProject()));
+
+		ConnectProviderOperation operation = new ConnectProviderOperation(
+				project.getProject(), gitDir);
+		operation.execute(null);
+
+		assertNotNull(RepositoryProvider.getProvider(project.getProject()));
+	}
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/CreatePatchOperationTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/CreatePatchOperationTest.java
new file mode 100644
index 0000000..fc4102e
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/CreatePatchOperationTest.java
@@ -0,0 +1,350 @@
+/*******************************************************************************
+ * Copyright (c) 2011, Tasktop Technologies
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Benjamin Muskalla (Tasktop Technologies) - initial implementation
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.File;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.egit.core.internal.op.CreatePatchOperation;
+import org.eclipse.egit.core.internal.op.CreatePatchOperation.DiffHeaderFormat;
+import org.eclipse.egit.core.internal.test.GitTestCase;
+import org.eclipse.egit.core.internal.test.TestProject;
+import org.eclipse.egit.core.internal.test.TestRepository;
+import org.eclipse.jgit.diff.DiffFormatter;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.util.FileUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class CreatePatchOperationTest extends GitTestCase {
+
+	private static final String SIMPLE_GIT_PATCH_CONTENT = "From 6dcd097c7d39e9ba0b31a380981d3fb46017d6c2 Sat, 23 Jul 2011 20:33:24 -0330\n"
+			+ "From: J. Git <j.git@egit.org>\n"
+			+ "Date: Sat, 15 Aug 2009 20:12:58 -0330\n"
+			+ "Subject: [PATCH] 2nd commit\n"
+			+ "\n"
+			+ "diff --git a/test-file b/test-file\n"
+			+ "index e69de29..eb5f2c9 100644\n"
+			+ "--- a/test-file\n"
+			+ "+++ b/test-file\n"
+			+ "@@ -0,0 +1 @@\n"
+			+ "+another line\n"
+			+ "\\ No newline at end of file";
+
+	private static final String SIMPLE_ONELINE_PATCH_CONTENT = "6dcd097c7d39e9ba0b31a380981d3fb46017d6c2 2nd commit\n"
+			+ "diff --git a/test-file b/test-file\n"
+			+ "index e69de29..eb5f2c9 100644\n"
+			+ "--- a/test-file\n"
+			+ "+++ b/test-file\n"
+			+ "@@ -0,0 +1 @@\n"
+			+ "+another line\n"
+			+ "\\ No newline at end of file";
+
+	private static final String SIMPLE_PATCH_CONTENT = "diff --git a/test-file b/test-file\n"
+			+ "index e69de29..eb5f2c9 100644\n"
+			+ "--- a/test-file\n"
+			+ "+++ b/test-file\n"
+			+ "@@ -0,0 +1 @@\n"
+			+ "+another line\n"
+			+ "\\ No newline at end of file";
+
+	private static final String SIMPLE_WORKSPACE_PATCH_CONTENT = "### Eclipse Workspace Patch 1.0\n"
+			+ "#P Project-1\n"
+			+ "diff --git deleted-file deleted-file\n"
+			+ "deleted file mode 100644\n"
+			+ "index e69de29..0000000\n"
+			+ "--- deleted-file\n"
+			+ "+++ /dev/null\n"
+			+ "diff --git new-file new-file\n"
+			+ "new file mode 100644\n"
+			+ "index 0000000..47d2739\n"
+			+ "--- /dev/null\n"
+			+ "+++ new-file\n"
+			+ "@@ -0,0 +1 @@\n"
+			+ "+new content\n"
+			+ "\\ No newline at end of file\n"
+			+ "diff --git test-file test-file\n"
+			+ "index e69de29..eb5f2c9 100644\n"
+			+ "--- test-file\n"
+			+ "+++ test-file\n"
+			+ "@@ -0,0 +1 @@\n"
+			+ "+another line\n"
+			+ "\\ No newline at end of file";
+
+	private RevCommit commit;
+
+	private File file;
+
+	private TestRepository testRepository;
+
+	@Before
+	public void setUp() throws Exception {
+		super.setUp();
+		gitDir = new File(project.getProject().getLocationURI().getPath(),
+				Constants.DOT_GIT);
+		testRepository = new TestRepository(gitDir);
+		testRepository.connect(project.getProject());
+
+		file = testRepository.createFile(project.getProject(), "test-file");
+
+		commit = testRepository.addAndCommit(project.getProject(), file,
+				"new file");
+	}
+
+	@After
+	public void tearDown() throws Exception {
+		testRepository.dispose();
+		super.tearDown();
+	}
+
+	@Test
+	public void testSimpleGitPatch() throws Exception {
+		RevCommit secondCommit = testRepository.appendContentAndCommit(
+				project.getProject(), file, "another line", "2nd commit");
+
+		CreatePatchOperation operation = new CreatePatchOperation(
+				testRepository.getRepository(), secondCommit);
+
+		operation.execute(new NullProgressMonitor());
+
+		String patchContent = operation.getPatchContent();
+		assertNotNull(patchContent);
+		assertGitPatch(SIMPLE_GIT_PATCH_CONTENT, patchContent);
+
+		// repeat setting the header format explicitly
+		operation = new CreatePatchOperation(
+				testRepository.getRepository(), secondCommit);
+
+		operation.setHeaderFormat(DiffHeaderFormat.EMAIL);
+		operation.execute(new NullProgressMonitor());
+
+		patchContent = operation.getPatchContent();
+		assertNotNull(patchContent);
+		assertGitPatch(SIMPLE_GIT_PATCH_CONTENT, patchContent);
+	}
+
+	@Test
+	public void testSimplePatch() throws Exception {
+		RevCommit secondCommit = testRepository.appendContentAndCommit(
+				project.getProject(), file, "another line", "2nd commit");
+
+		CreatePatchOperation operation = new CreatePatchOperation(
+				testRepository.getRepository(), secondCommit);
+
+		operation.setHeaderFormat(DiffHeaderFormat.NONE);
+		operation.execute(new NullProgressMonitor());
+
+		String patchContent = operation.getPatchContent();
+		assertNotNull(patchContent);
+		assertPatch(SIMPLE_PATCH_CONTENT, patchContent);
+	}
+
+	@Test
+	public void testOnelineHeaderPatch() throws Exception {
+		RevCommit secondCommit = testRepository.appendContentAndCommit(
+				project.getProject(), file, "another line", "2nd commit");
+
+		CreatePatchOperation operation = new CreatePatchOperation(
+				testRepository.getRepository(), secondCommit);
+
+		operation.setHeaderFormat(DiffHeaderFormat.ONELINE);
+		operation.execute(new NullProgressMonitor());
+
+		String patchContent = operation.getPatchContent();
+		assertNotNull(patchContent);
+		assertPatch(SIMPLE_ONELINE_PATCH_CONTENT, patchContent);
+	}
+
+	@Test(expected = IllegalStateException.class)
+	public void testFirstCommit() throws Exception {
+		CreatePatchOperation operation = new CreatePatchOperation(
+				testRepository.getRepository(), commit);
+
+		operation.execute(null);
+	}
+
+	@Test
+	public void testNullCommit() throws Exception {
+		new CreatePatchOperation(testRepository.getRepository(), null);
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void testNullRepo() throws Exception {
+		new CreatePatchOperation(null, commit);
+	}
+
+	@Test(expected = IllegalStateException.class)
+	public void testExecuteFirst() throws Exception {
+		CreatePatchOperation operation = new CreatePatchOperation(
+				testRepository.getRepository(), commit);
+		operation.getPatchContent();
+	}
+
+	@Test
+	public void testNullMonitor() throws Exception {
+		RevCommit secondCommit = testRepository.appendContentAndCommit(
+				project.getProject(), file, "another line", "2nd commit");
+		CreatePatchOperation operation = new CreatePatchOperation(
+				testRepository.getRepository(), secondCommit);
+		operation.execute(null);
+	}
+
+	@Test
+	public void testSuggestName() throws Exception {
+		RevCommit aCommit = testRepository.appendContentAndCommit(
+				project.getProject(), file, "another line", "2nd commit");
+		assertEquals("2nd-commit.patch", CreatePatchOperation.suggestFileName(aCommit));
+
+		aCommit = testRepository.appendContentAndCommit(
+				project.getProject(), file, "another line", "[findBugs] Change visibility of repositoryFile to package");
+		assertEquals("findBugs-Change-visibility-of-repositoryFile-to-pack.patch", CreatePatchOperation.suggestFileName(aCommit));
+
+		aCommit = testRepository.appendContentAndCommit(
+				project.getProject(), file, "another line", "Add collapse/expand all utility method for tree viewers.");
+		assertEquals("Add-collapse-expand-all-utility-method-for-tree-view.patch", CreatePatchOperation.suggestFileName(aCommit));
+	}
+
+	@Test
+	public void testComputeWorkspacePath() throws Exception {
+		IPath oldPath = CreatePatchOperation.computeWorkspacePath(new Path(
+				"test-file"), project.getProject());
+		IPath newPath = CreatePatchOperation.computeWorkspacePath(new Path(
+				"test-file"), project.getProject());
+		assertPatch("test-file", oldPath.toString());
+		assertPatch("test-file", newPath.toString());
+	}
+
+	@Test
+	public void testComputeWorkspacePathRepoAboveProject() throws Exception {
+		testRepository.disconnect(project.getProject());
+
+		// new setup
+		project = new TestProject(true, "repo/bundles/Project-1", true, null);
+		File repo = new File(project.getProject().getLocationURI().getPath())
+				.getParentFile().getParentFile();
+		gitDir = new File(repo, Constants.DOT_GIT);
+		testRepository = new TestRepository(gitDir);
+		testRepository.connect(project.getProject());
+
+		IPath oldPath = CreatePatchOperation.computeWorkspacePath(new Path(
+				"bundles/Project-1/test-file"), project.getProject());
+		IPath newPath = CreatePatchOperation.computeWorkspacePath(new Path(
+				"bundles/Project-1/test-file"), project.getProject());
+		assertPatch("test-file", oldPath.toString());
+		assertPatch("test-file", newPath.toString());
+	}
+
+	@Test
+	public void testUpdateWorkspacePatchPrefixes() throws Exception {
+		// setup workspace
+		File newFile = testRepository.createFile(project.getProject(), "new-file");
+		testRepository.appendFileContent(newFile, "new content");
+		File deletedFile = testRepository.createFile(project.getProject(), "deleted-file");
+		commit = testRepository.addAndCommit(project.getProject(), deletedFile,
+				"whatever");
+		FileUtils.delete(deletedFile);
+
+		// unprocessed patch
+		DiffFormatter diffFmt = new DiffFormatter(null);
+		diffFmt.setRepository(testRepository.getRepository());
+		StringBuilder sb = new StringBuilder();
+		sb.append("diff --git a/deleted-file b/deleted-file").append("\n");
+		sb.append("deleted file mode 100644").append("\n");
+		sb.append("index e69de29..0000000").append("\n");
+		sb.append("--- a/deleted-file").append("\n");
+		sb.append("+++ /dev/null").append("\n");
+		sb.append("diff --git a/new-file b/new-file").append("\n");
+		sb.append("new file mode 100644").append("\n");
+		sb.append("index 0000000..47d2739").append("\n");
+		sb.append("--- /dev/null").append("\n");
+		sb.append("+++ b/new-file").append("\n");
+		sb.append("@@ -0,0 +1 @@").append("\n");
+		sb.append("+new content").append("\n");
+		sb.append("\\ No newline at end of file").append("\n");
+		sb.append(SIMPLE_PATCH_CONTENT);
+
+		// update patch
+		CreatePatchOperation op = new CreatePatchOperation(testRepository.getRepository(), null);
+		op.updateWorkspacePatchPrefixes(sb, diffFmt);
+		// add workspace header
+		StringBuilder sb1 = new StringBuilder("### Eclipse Workspace Patch 1.0\n#P ")
+				.append(project.getProject().getName()).append("\n").append(sb);
+
+		assertPatch(SIMPLE_WORKSPACE_PATCH_CONTENT, sb1.toString());
+	}
+
+	@Test
+	public void testWorkspacePatchForCommit() throws Exception {
+		// setup workspace
+		File deletedFile = testRepository.createFile(project.getProject(), "deleted-file");
+		commit = testRepository.addAndCommit(project.getProject(), deletedFile,
+				"whatever");
+		FileUtils.delete(deletedFile);
+		testRepository.appendFileContent(file, "another line");
+		File newFile = testRepository.createFile(project.getProject(), "new-file");
+		testRepository.appendFileContent(newFile, "new content");
+		testRepository.untrack(deletedFile);
+		testRepository.track(file);
+		testRepository.track(newFile);
+		commit = testRepository.commit("2nd commit");
+
+		// create patch
+		CreatePatchOperation operation = new CreatePatchOperation(
+				testRepository.getRepository(), commit);
+
+		operation.setHeaderFormat(DiffHeaderFormat.WORKSPACE);
+		operation.execute(new NullProgressMonitor());
+
+		assertPatch(SIMPLE_WORKSPACE_PATCH_CONTENT, operation.getPatchContent());
+	}
+
+	@Test
+	public void testWorkspacePatchForWorkingDir() throws Exception {
+		// setup workspace
+		testRepository.addToIndex(project.getProject().findMember(".classpath"));
+		testRepository.addToIndex(project.getProject().findMember(".project"));
+		testRepository.commit("commit all");
+		testRepository.appendFileContent(file, "another line");
+		File newFile = testRepository.createFile(project.getProject(), "new-file");
+		testRepository.appendFileContent(newFile, "new content");
+		File deletedFile = testRepository.createFile(project.getProject(), "deleted-file");
+		commit = testRepository.addAndCommit(project.getProject(), deletedFile,
+				"whatever");
+		FileUtils.delete(deletedFile);
+
+		// create patch
+		CreatePatchOperation operation = new CreatePatchOperation(
+				testRepository.getRepository(), null);
+
+		operation.setHeaderFormat(DiffHeaderFormat.WORKSPACE);
+		operation.execute(new NullProgressMonitor());
+
+		assertPatch(SIMPLE_WORKSPACE_PATCH_CONTENT, operation.getPatchContent());
+	}
+
+	private void assertGitPatch(String expected, String actual) {
+		assertEquals(expected.substring(0,45), actual.substring(0,45));
+		assertEquals(expected.substring(expected.indexOf("\n")), actual.substring(actual.indexOf("\n")));
+	}
+
+	private void assertPatch(String expected, String actual) {
+		assertEquals(expected, actual);
+	}
+
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/DeletePathsOperationTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/DeletePathsOperationTest.java
new file mode 100644
index 0000000..bf1602a
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/DeletePathsOperationTest.java
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * Copyright (C) 2012, Robin Stocker <robin@nibor.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.JobFamilies;
+import org.eclipse.egit.core.internal.indexdiff.IndexDiffCache;
+import org.eclipse.egit.core.internal.indexdiff.IndexDiffCacheEntry;
+import org.eclipse.egit.core.internal.op.DeletePathsOperation;
+import org.eclipse.egit.core.internal.test.DualRepositoryTestCase;
+import org.eclipse.egit.core.internal.test.JobSchedulingAssert;
+import org.eclipse.egit.core.internal.test.TestRepository;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.Repository;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class DeletePathsOperationTest extends DualRepositoryTestCase {
+
+	File workdir;
+
+	IProject project;
+
+	String projectName = "DeletePathsOperationTest";
+
+	@Before
+	public void setUp() throws Exception {
+
+		workdir = testUtils.createTempDir("Repository1");
+
+		repository1 = new TestRepository(new File(workdir, Constants.DOT_GIT));
+		project = testUtils.createProjectInLocalFileSystem(workdir, projectName);
+		repository1.connect(project);
+	}
+
+	@After
+	public void tearDown() throws Exception {
+		Job.getJobManager().join(JobFamilies.INDEX_DIFF_CACHE_UPDATE, null);
+		project.close(null);
+		project.delete(false, false, null);
+		repository1.dispose();
+		repository1 = null;
+		testUtils.deleteTempDirs();
+	}
+
+	@Test
+	public void testDeleteResourceOfProject() throws Exception {
+		IResource resource = testUtils.addFileToProject(project, "file.txt", "Hello world 1");
+
+		deletePaths(Arrays.asList(resource.getLocation()));
+
+		File file = resource.getFullPath().toFile();
+		assertFalse("File should have been deleted", file.exists());
+	}
+
+	@Test
+	public void testDeleteResourceOutsideOfProject() throws Exception {
+		File outsideOfProject = new File(workdir, "outside-of-project.txt");
+		outsideOfProject.createNewFile();
+
+		IPath path = new Path(outsideOfProject.getAbsolutePath());
+
+		// Make sure the cache has at least be refreshed once, otherwise the
+		// assertion at the end is not effective
+		initIndexDiffCache(repository1.getRepository());
+
+		JobSchedulingAssert jobSchedulingAssertion = JobSchedulingAssert
+				.forFamily(JobFamilies.INDEX_DIFF_CACHE_UPDATE);
+		deletePaths(Arrays.asList(path));
+
+		assertFalse("File should have been deleted", outsideOfProject.exists());
+		jobSchedulingAssertion
+				.assertScheduled("Delete of file outside of workspace should have cause an index diff cache job.");
+	}
+
+	private static void initIndexDiffCache(Repository repository)
+			throws Exception {
+		IndexDiffCache cache = Activator.getDefault().getIndexDiffCache();
+		IndexDiffCacheEntry cacheEntry = cache.getIndexDiffCacheEntry(repository);
+		assertNotNull(cacheEntry);
+		Job.getJobManager().join(JobFamilies.INDEX_DIFF_CACHE_UPDATE, null);
+	}
+
+	private void deletePaths(Collection<IPath> paths) throws CoreException {
+		DeletePathsOperation operation = new DeletePathsOperation(paths);
+		operation.execute(null);
+	}
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/DiscardChangesOperationTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/DiscardChangesOperationTest.java
new file mode 100644
index 0000000..0f679d6
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/DiscardChangesOperationTest.java
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Mathias Kinzler <mathias.kinzler@sap.com>
+ * Copyright (C) 2012, Robin Stocker <robin@nibor.org>
+ * Copyright (C) 2012, François Rey <eclipse.org_@_francois_._rey_._name>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.egit.core.internal.op.DiscardChangesOperation;
+import org.eclipse.egit.core.internal.test.DualRepositoryTestCase;
+import org.eclipse.egit.core.internal.test.TestRepository;
+import org.eclipse.jgit.lib.Constants;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class DiscardChangesOperationTest extends DualRepositoryTestCase {
+
+	File workdir;
+
+	IProject project;
+	IProject project2;
+
+	String projectName = "DiscardChangesTest";
+
+	@Before
+	public void setUp() throws Exception {
+
+		workdir = testUtils.createTempDir("Repository1");
+
+		repository1 = new TestRepository(new File(workdir, Constants.DOT_GIT));
+
+		// now we create a project in repo1
+		project = testUtils
+				.createProjectInLocalFileSystem(workdir, projectName);
+		testUtils.addFileToProject(project, "folder1/file1.txt", "Hello world 1");
+		testUtils.addFileToProject(project, "folder1/file2.txt", "Hello world 2");
+
+		repository1.connect(project);
+		repository1.trackAllFiles(project);
+		repository1.commit("Initial commit");
+
+		File workdir2 = testUtils.createTempDir("Project2");
+		// Project location is at root of repository
+		project2 = testUtils.createProjectInLocalFileSystem(workdir2.getParentFile(), "Project2");
+		testUtils.addFileToProject(project2, "file.txt", "initial");
+		repository2 = new TestRepository(new File(workdir2, Constants.DOT_GIT));
+		repository2.connect(project2);
+		repository2.trackAllFiles(project2);
+		repository2.commit("Initial commit");
+	}
+
+	@After
+	public void tearDown() throws Exception {
+		project.close(null);
+		project.delete(false, false, null);
+		project2.close(null);
+		project2.delete(false, false, null);
+		repository1.dispose();
+		repository1 = null;
+		repository2.dispose();
+		repository2 = null;
+		testUtils.deleteTempDirs();
+	}
+
+	@Test
+	public void testDiscardChanges() throws Exception {
+		IFile file1 = project.getFile(new Path("folder1/file1.txt"));
+		String contents = testUtils.slurpAndClose(file1.getContents());
+		assertEquals("Hello world 1", contents);
+		setNewFileContent(file1, "changed 1");
+
+		IFile file2 = project.getFile(new Path("folder1/file2.txt"));
+		contents = testUtils.slurpAndClose(file2.getContents());
+		assertEquals("Hello world 2", contents);
+		setNewFileContent(file2, "changed 2");
+
+		DiscardChangesOperation dcop = new DiscardChangesOperation(
+				new IResource[] { file1, file2 });
+		dcop.execute(new NullProgressMonitor());
+
+		contents = testUtils.slurpAndClose(file1.getContents());
+		assertEquals("Hello world 1", contents);
+
+		contents = testUtils.slurpAndClose(file2.getContents());
+		assertEquals("Hello world 2", contents);
+	}
+
+	@Test
+	public void shouldWorkWhenProjectIsRootOfRepository() throws Exception {
+		IFile file = project2.getFile(new Path("file.txt"));
+		String contents = testUtils.slurpAndClose(file.getContents());
+		assertEquals("initial", contents);
+		setNewFileContent(file, "changed");
+
+		DiscardChangesOperation dcop = new DiscardChangesOperation(new IResource[] { project2 });
+		dcop.execute(new NullProgressMonitor());
+
+		String replacedContents = testUtils.slurpAndClose(file.getContents());
+		assertEquals("initial", replacedContents);
+	}
+
+	private void setNewFileContent(IFile file, String content) throws Exception {
+		file.setContents(
+				new ByteArrayInputStream(content.getBytes(project
+						.getDefaultCharset())), 0, null);
+		assertEquals(content, testUtils.slurpAndClose(file.getContents()));
+	}
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/IgnoreOperationTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/IgnoreOperationTest.java
new file mode 100644
index 0000000..3de9f55
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/IgnoreOperationTest.java
@@ -0,0 +1,155 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Benjamin Muskalla <bmuskalla@eclipsesource.com>
+ * Copyright (C) 2012, 2013 Robin Stocker <robin@nibor.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+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 java.io.ByteArrayInputStream;
+import java.io.File;
+import java.util.Arrays;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.egit.core.internal.op.IgnoreOperation;
+import org.eclipse.egit.core.internal.test.GitTestCase;
+import org.eclipse.egit.core.internal.test.TestRepository;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.util.FileUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class IgnoreOperationTest extends GitTestCase {
+
+	private TestRepository testRepository;
+
+	@Before
+	public void setUp() throws Exception {
+		super.setUp();
+		testRepository = new TestRepository(gitDir);
+		testRepository.connect(project.getProject());
+	}
+
+	@After
+	public void tearDown() throws Exception {
+		testRepository.dispose();
+		// delete gitignore file in workspace folder
+		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+		File rootFile = root.getRawLocation().toFile();
+		File ignoreFile = new File(rootFile, Constants.GITIGNORE_FILENAME);
+		if (ignoreFile.exists()) {
+			FileUtils.delete(ignoreFile, FileUtils.RETRY);
+			assert !ignoreFile.exists();
+		}
+		super.tearDown();
+	}
+
+	@Test
+	public void testIgnoreFolder() throws Exception {
+		IFolder binFolder = project.getProject().getFolder("bin");
+		IgnoreOperation operation = executeIgnore(binFolder.getLocation());
+
+		String content = project.getFileContent(Constants.GITIGNORE_FILENAME);
+		assertEquals("/bin\n", content);
+		assertFalse(operation.isGitignoreOutsideWSChanged());
+	}
+
+	@Test
+	public void testIgnoreFileCancel() throws Exception {
+		IFolder binFolder = project.getProject().getFolder("bin");
+		IgnoreOperation operation = new IgnoreOperation(Arrays.asList(binFolder.getLocation()));
+		NullProgressMonitor monitor = new NullProgressMonitor();
+		monitor.setCanceled(true);
+		operation.execute(monitor);
+
+		assertFalse(project.getProject().getFile(Constants.GITIGNORE_FILENAME).exists());
+	}
+
+
+	@Test
+	public void testSchedulingRule() throws Exception {
+		IFolder binFolder = project.getProject().getFolder("bin");
+		IgnoreOperation operation = executeIgnore(binFolder.getLocation());
+
+		assertNotNull(operation.getSchedulingRule());
+	}
+
+	@Test
+	public void testIgnoreMultiFile() throws Exception {
+		project.createSourceFolder();
+		IFolder binFolder = project.getProject().getFolder("bin");
+		IFolder srcFolder = project.getProject().getFolder("src");
+		executeIgnore(binFolder.getLocation());
+
+		String content = project.getFileContent(Constants.GITIGNORE_FILENAME);
+		assertEquals("/bin\n", content);
+
+		executeIgnore(srcFolder.getLocation());
+
+		content = project.getFileContent(Constants.GITIGNORE_FILENAME);
+		assertEquals("/bin\n/src\n", content);
+	}
+
+	@Test
+	public void testIgnoreProject() throws Exception {
+		IgnoreOperation operation = executeIgnore(
+				project.getProject().getLocation());
+
+		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+		File rootFile = root.getRawLocation().toFile();
+		File ignoreFile = new File(rootFile, Constants.GITIGNORE_FILENAME);
+		String content = testUtils.slurpAndClose(ignoreFile.toURI().toURL()
+				.openStream());
+		assertEquals("/" + project.getProject().getName() + "\n", content);
+		assertTrue(operation.isGitignoreOutsideWSChanged());
+	}
+
+	@Test
+	public void testIgnoreNoTrailingNewline() throws Exception {
+		String existing = "/nonewline";
+		IFile ignore = project.getProject().getFile(
+				Constants.GITIGNORE_FILENAME);
+		assertFalse(ignore.exists());
+		ignore.create(new ByteArrayInputStream(existing.getBytes()),
+				IResource.FORCE, new NullProgressMonitor());
+
+		IFolder binFolder = project.getProject().getFolder("bin");
+		IgnoreOperation operation = executeIgnore(binFolder.getLocation());
+
+		String content = project.getFileContent(Constants.GITIGNORE_FILENAME);
+		assertEquals(existing + "\n/bin\n", content);
+		assertFalse(operation.isGitignoreOutsideWSChanged());
+	}
+
+	@Test
+	public void testIgnoreWithResource() throws Exception {
+		IFolder binFolder = project.getProject().getFolder("bin");
+		@SuppressWarnings("deprecation")
+		IgnoreOperation operation = new IgnoreOperation(new IResource[] {binFolder});
+		operation.execute(new NullProgressMonitor());
+
+		String content = project.getFileContent(Constants.GITIGNORE_FILENAME);
+		assertEquals("/bin\n", content);
+	}
+
+	private IgnoreOperation executeIgnore(IPath... paths) throws Exception {
+		IgnoreOperation operation = new IgnoreOperation(Arrays.asList(paths));
+		operation.execute(new NullProgressMonitor());
+		return operation;
+	}
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/ListRemoteOperationTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/ListRemoteOperationTest.java
new file mode 100644
index 0000000..ebf42bf
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/ListRemoteOperationTest.java
@@ -0,0 +1,158 @@
+/*******************************************************************************
+ * Copyright (C) 2010, 2012 Mathias Kinzler <mathias.kinzler@sap.com> and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.op.CloneOperation;
+import org.eclipse.egit.core.internal.op.ListRemoteOperation;
+import org.eclipse.egit.core.internal.test.DualRepositoryTestCase;
+import org.eclipse.egit.core.internal.test.TestRepository;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.RefUpdate;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.transport.URIish;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ListRemoteOperationTest extends DualRepositoryTestCase {
+
+	File workdir;
+
+	File workdir2;
+
+	String projectName = "ListRemoteTest";
+
+	/**
+	 * Set up repository1 with branch "master", create some project and commit
+	 * it; then clone into repository2; finally create a branch "test" on top of
+	 * "master" in repository2
+	 *
+	 * @throws Exception
+	 */
+	@Before
+	public void setUp() throws Exception {
+
+		workdir = testUtils.createTempDir("Repository1");
+		workdir2 = testUtils.createTempDir("Repository2");
+
+		repository1 = new TestRepository(new File(workdir, Constants.DOT_GIT));
+
+		// now we create a project in repo1
+		IProject project = testUtils.createProjectInLocalFileSystem(workdir,
+				projectName);
+		testUtils.addFileToProject(project, "folder1/file1.txt", "Hello world");
+
+		repository1.connect(project);
+		repository1.trackAllFiles(project);
+		repository1.commit("Initial commit");
+
+		// let's get rid of the project
+		project.delete(false, false, null);
+
+		// let's clone repository1 to repository2
+		URIish uri = new URIish("file:///"
+				+ repository1.getRepository().getDirectory().toString());
+		CloneOperation clop = new CloneOperation(uri, true, null, workdir2,
+				"refs/heads/master", "origin", 0);
+		clop.run(null);
+
+		Repository existingRepo = Activator
+				.getDefault()
+				.getRepositoryCache()
+				.lookupRepository(
+						new File(workdir2, Constants.DOT_GIT));
+		repository2 = new TestRepository(existingRepo);
+		// we push to branch "test" of repository2
+		RefUpdate createBranch = repository2.getRepository().updateRef(
+				"refs/heads/test");
+		createBranch.setNewObjectId(repository2.getRepository().resolve(
+				"refs/heads/master"));
+		createBranch.update();
+	}
+
+	@After
+	public void tearDown() throws Exception {
+		repository1.dispose();
+		repository2.dispose();
+		testUtils.deleteTempDirs();
+	}
+
+	/**
+	 * List the refs both ways
+	 *
+	 * @throws Exception
+	 */
+	@Test
+	public void testListRemote() throws Exception {
+
+		URIish uri = new URIish("file:///"
+				+ repository2.getRepository().getDirectory().getPath());
+		ListRemoteOperation lrop = new ListRemoteOperation(repository1
+				.getRepository(), uri, 0);
+		lrop.run(null);
+		assertEquals(4, lrop.getRemoteRefs().size());
+		assertNotNull(lrop.getRemoteRef("refs/heads/test"));
+
+		uri = new URIish("file:///"
+				+ repository1.getRepository().getDirectory().getPath());
+		lrop = new ListRemoteOperation(repository2.getRepository(), uri, 0);
+		lrop.run(new NullProgressMonitor());
+		assertEquals(2, lrop.getRemoteRefs().size());
+		assertNotNull(lrop.getRemoteRef("refs/heads/master"));
+	}
+
+	/**
+	 * Call getRemoteRefs without having run the op
+	 *
+	 * @throws Exception
+	 */
+	@Test
+	public void testIllegalStateException() throws Exception {
+
+		URIish uri = new URIish("file:///"
+				+ repository2.getRepository().getDirectory().getPath());
+		ListRemoteOperation lrop = new ListRemoteOperation(repository1
+				.getRepository(), uri, 0);
+		try {
+			lrop.getRemoteRefs();
+			fail("Expected Exception not thrown");
+		} catch (IllegalStateException e) {
+			// expected
+		}
+	}
+
+	/**
+	 * Test with illegal URI
+	 *
+	 * @throws Exception
+	 */
+	@Test
+	public void testIllegalURI() throws Exception {
+
+		URIish uri = new URIish("file:///" + "no/path");
+		ListRemoteOperation lrop = new ListRemoteOperation(repository1
+				.getRepository(), uri, 0);
+		try {
+			lrop.run(new NullProgressMonitor());
+			fail("Expected Exception not thrown");
+		} catch (InvocationTargetException e) {
+			// expected
+		}
+	}
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/MergeOperationTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/MergeOperationTest.java
new file mode 100644
index 0000000..58392f1
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/MergeOperationTest.java
@@ -0,0 +1,154 @@
+/*******************************************************************************
+ * Copyright (C) 2013, Tomasz Zarna <tomasz.zarna@gmail.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Iterator;
+
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.egit.core.internal.op.MergeOperation;
+import org.eclipse.egit.core.internal.test.GitTestCase;
+import org.eclipse.egit.core.internal.test.TestRepository;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.LogCommand;
+import org.eclipse.jgit.api.MergeCommand.FastForwardMode;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.lib.ConfigConstants;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.StoredConfig;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class MergeOperationTest extends GitTestCase {
+
+	private static final String MASTER = Constants.R_HEADS +  Constants.MASTER;
+	private static final String SIDE = Constants.R_HEADS + "side";
+
+	private TestRepository testRepository;
+	private RevCommit secondCommit;
+
+	@Before
+	public void setUp() throws Exception {
+		super.setUp();
+		gitDir = new File(project.getProject()
+				.getLocationURI().getPath(), Constants.DOT_GIT);
+		testRepository = new TestRepository(gitDir);
+		testRepository.connect(project.getProject());
+
+		File file1 = testRepository.createFile(project.getProject(), "file1-1");
+		testRepository.addAndCommit(project.getProject(), file1,
+				"master commit 1");
+		testRepository.createBranch(MASTER, SIDE);
+		testRepository.appendFileContent(file1, "file1-2");
+		secondCommit = testRepository.addAndCommit(project.getProject(), file1,
+				"master commit 2");
+		testRepository.checkoutBranch(SIDE);
+	}
+
+	@After
+	public void tearDown() throws Exception {
+		testRepository.dispose();
+		super.tearDown();
+	}
+
+	@Test
+	public void testMergeFF() throws Exception {
+		MergeOperation operation = new MergeOperation(
+				testRepository.getRepository(), MASTER);
+		operation.execute(new NullProgressMonitor());
+
+		assertTrue(testRepository.getRepository().resolve(SIDE).equals(secondCommit));
+		assertEquals(2, countCommitsInHead());
+	}
+
+	@Test
+	public void testMergeoptionsNoFF() throws Exception {
+		setMergeOptions("side", FastForwardMode.NO_FF);
+
+		MergeOperation operation = new MergeOperation(
+				testRepository.getRepository(), MASTER);
+		operation.execute(new NullProgressMonitor());
+
+		assertEquals(3, countCommitsInHead());
+	}
+
+	@Test
+	public void testMergeoptionsFFOnly() throws Exception {
+		setMergeOptions("side", FastForwardMode.FF_ONLY);
+		File file2 = testRepository.createFile(project.getProject(), "file2");
+		testRepository.appendFileContent(file2, "file2-1");
+		RevCommit commit = testRepository.addAndCommit(project.getProject(), file2,
+				"side commit 1");
+
+		MergeOperation operation = new MergeOperation(
+				testRepository.getRepository(), MASTER);
+		operation.execute(new NullProgressMonitor());
+
+		assertTrue(testRepository.getRepository().resolve(SIDE).equals(commit));
+	}
+
+	private void setMergeOptions(String branch, FastForwardMode ffMode)
+			throws IOException {
+		StoredConfig config = testRepository.getRepository().getConfig();
+		config.setEnum(ConfigConstants.CONFIG_BRANCH_SECTION, branch,
+				ConfigConstants.CONFIG_KEY_MERGEOPTIONS, ffMode);
+		config.save();
+	}
+
+	@Test
+	public void testMergeNoFF() throws Exception {
+		setMerge(FastForwardMode.NO_FF);
+
+		MergeOperation operation = new MergeOperation(
+				testRepository.getRepository(), MASTER);
+		operation.execute(new NullProgressMonitor());
+
+		assertEquals(3, countCommitsInHead());
+	}
+
+	@Test
+	public void testMergeFFOnly() throws Exception {
+		setMerge(FastForwardMode.FF_ONLY);
+		File file2 = testRepository.createFile(project.getProject(), "file2");
+		testRepository.appendFileContent(file2, "file2-1");
+		RevCommit commit = testRepository.addAndCommit(project.getProject(), file2,
+				"side commit 1");
+
+		MergeOperation operation = new MergeOperation(
+				testRepository.getRepository(), MASTER);
+		operation.execute(new NullProgressMonitor());
+
+		assertTrue(testRepository.getRepository().resolve(SIDE).equals(commit));
+	}
+
+	private void setMerge(FastForwardMode ffMode) throws IOException {
+		StoredConfig config = testRepository.getRepository().getConfig();
+		config.setEnum(ConfigConstants.CONFIG_KEY_MERGE, null,
+				ConfigConstants.CONFIG_KEY_FF,
+				FastForwardMode.Merge.valueOf(ffMode));
+		config.save();
+	}
+
+	private int countCommitsInHead() throws GitAPIException {
+		LogCommand log = new Git(testRepository.getRepository()).log();
+		Iterable<RevCommit> commits = log.call();
+		int result = 0;
+		for (Iterator i = commits.iterator(); i.hasNext();) {
+			i.next();
+			result++;
+		}
+		return result;
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/PushOperationTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/PushOperationTest.java
new file mode 100644
index 0000000..1720a92
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/PushOperationTest.java
@@ -0,0 +1,339 @@
+/*******************************************************************************
+ * Copyright (C) 2010, 2012 Mathias Kinzler <mathias.kinzler@sap.com> and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+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.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.ILog;
+import org.eclipse.core.runtime.ILogListener;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.op.AddToIndexOperation;
+import org.eclipse.egit.core.internal.op.BranchOperation;
+import org.eclipse.egit.core.internal.op.CloneOperation;
+import org.eclipse.egit.core.internal.op.CommitOperation;
+import org.eclipse.egit.core.internal.op.PushOperation;
+import org.eclipse.egit.core.internal.op.PushOperationResult;
+import org.eclipse.egit.core.internal.op.PushOperationSpecification;
+import org.eclipse.egit.core.internal.test.DualRepositoryTestCase;
+import org.eclipse.egit.core.internal.test.TestRepository;
+import org.eclipse.egit.core.internal.test.TestUtils;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.RefUpdate;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.transport.PushResult;
+import org.eclipse.jgit.transport.RemoteRefUpdate;
+import org.eclipse.jgit.transport.RemoteRefUpdate.Status;
+import org.eclipse.jgit.transport.URIish;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class PushOperationTest extends DualRepositoryTestCase {
+
+
+	private static final String INVALID_URI = "invalid-uri";
+
+	File workdir;
+
+	File workdir2;
+
+	String projectName = "PushTest";
+
+	/**
+	 * Set up repository1 with branch "master", create some project and commit
+	 * it; then clone into repository2; finally create a branch "test" on top of
+	 * "master" in repository2
+	 *
+	 * @throws Exception
+	 */
+	@Before
+	public void setUp() throws Exception {
+
+		workdir = testUtils.createTempDir("Repository1");
+		workdir2 = testUtils.createTempDir("Repository2");
+
+		repository1 = new TestRepository(new File(workdir, Constants.DOT_GIT));
+
+		// now we create a project in repo1
+		IProject project = testUtils.createProjectInLocalFileSystem(workdir,
+				projectName);
+		testUtils.addFileToProject(project, "folder1/file1.txt", "Hello world");
+
+		repository1.connect(project);
+		repository1.trackAllFiles(project);
+		repository1.commit("Initial commit");
+
+		// let's get rid of the project
+		project.delete(false, false, null);
+
+		// let's clone repository1 to repository2
+		URIish uri = repository1.getUri();
+		CloneOperation clop = new CloneOperation(uri, true, null, workdir2,
+				"refs/heads/master", "origin", 0);
+		clop.run(null);
+
+		Repository repo2 = Activator.getDefault().getRepositoryCache().lookupRepository(new File(workdir2,
+				Constants.DOT_GIT));
+		repository2 = new TestRepository(repo2);
+		// we push to branch "test" of repository2
+		RefUpdate createBranch = repository2.getRepository().updateRef(
+				"refs/heads/test");
+		createBranch.setNewObjectId(repository2.getRepository().resolve(
+				"refs/heads/master"));
+		createBranch.update();
+	}
+
+	@After
+	public void tearDown() throws Exception {
+		repository1.dispose();
+		repository2.dispose();
+		repository1 = null;
+		repository2 = null;
+		testUtils.deleteTempDirs();
+	}
+
+	/**
+	 * Push from repository1 "master" into "test" of repository2.
+	 *
+	 * @throws Exception
+	 */
+	@Test
+	public void testPush() throws Exception {
+
+		// push from repository1 to repository2
+		PushOperation pop = createPushOperation();
+		pop.run(new NullProgressMonitor());
+		assertEquals(Status.UP_TO_DATE, getStatus(pop.getOperationResult()));
+
+		// let's add a new file to the project shared with repository1
+		IProject proj = importProject(repository1, projectName);
+		ArrayList<IFile> files = new ArrayList<IFile>();
+		IFile newFile = testUtils.addFileToProject(proj, "folder2/file2.txt",
+				"New file");
+		files.add(newFile);
+		IFile[] fileArr = files.toArray(new IFile[files.size()]);
+
+		AddToIndexOperation trop = new AddToIndexOperation(files);
+		trop.execute(null);
+		CommitOperation cop = new CommitOperation(fileArr, files, TestUtils.AUTHOR,
+				TestUtils.COMMITTER, "Added file");
+		cop.execute(null);
+
+		proj.delete(false, false, null);
+
+		pop = createPushOperation();
+		pop.run(null);
+		assertEquals(Status.OK, getStatus(pop.getOperationResult()));
+
+		try {
+			// assert that we can not run this again
+			pop.run(null);
+			fail("Expected Exception not thrown");
+		} catch (IllegalStateException e) {
+			// expected
+		}
+
+		pop = createPushOperation();
+		pop.run(null);
+		assertEquals(Status.UP_TO_DATE, getStatus(pop.getOperationResult()));
+
+		String newFilePath = newFile.getFullPath().toOSString();
+
+		File testFile = new File(workdir2, newFilePath);
+		assertFalse(testFile.exists());
+		testFile = new File(workdir, newFilePath);
+		assertTrue(testFile.exists());
+
+		// check out test and verify the file is there
+		BranchOperation bop = new BranchOperation(repository2.getRepository(),
+				"refs/heads/test");
+		bop.execute(null);
+		testFile = new File(workdir2, newFilePath);
+		assertTrue(testFile.exists());
+	}
+
+	/**
+	 * An invalid URI should yield an operation result with an error message
+	 * and the exception should be logged
+	 *
+	 * @throws Exception
+	 */
+	@Test
+	public void testInvalidUriDuringPush() throws Exception {
+		ILog log = Activator.getDefault().getLog();
+		LogListener listener = new LogListener();
+		log.addLogListener(listener);
+
+		PushOperation pop = createInvalidPushOperation();
+		pop.run(new NullProgressMonitor());
+		PushOperationResult result = pop.getOperationResult();
+		String errorMessage = result.getErrorMessage(new URIish(INVALID_URI));
+		assertNotNull(errorMessage);
+		assertTrue(errorMessage.contains(INVALID_URI));
+
+		assertTrue(listener.loggedSomething());
+		assertTrue(listener.loggedException());
+
+	}
+
+	private PushOperation createInvalidPushOperation() throws Exception {
+		// set up push with invalid URI to provoke an exception
+		PushOperationSpecification spec = new PushOperationSpecification();
+		// the remote is invalid
+		URIish remote = new URIish(INVALID_URI);
+		// update master upon master
+		Repository local = repository1.getRepository();
+		RemoteRefUpdate update = new RemoteRefUpdate(local, "HEAD", "refs/heads/test",
+				false, null, null);
+		spec.addURIRefUpdates(remote, Collections.singletonList(update));
+		// now we can construct the push operation
+		PushOperation pop = new PushOperation(local, spec, false, 0);
+		return pop;
+	}
+
+	private static final class LogListener implements ILogListener {
+		private boolean loggedSomething = false;
+		private boolean loggedException = false;
+
+		public void logging(IStatus status, String plugin) {
+			loggedSomething = true;
+			loggedException = status.getException() != null;
+		}
+
+		public boolean loggedSomething() {
+			return loggedSomething;
+		}
+
+		public boolean loggedException() {
+			return loggedException;
+		}
+
+}
+
+	/**
+	 * We should get an {@link IllegalStateException} if we run
+	 * getOperationResult before run()
+	 *
+	 * @throws Exception
+	 */
+	@Test
+	public void testIllegalStateExceptionOnGetResultWithoutRun()
+			throws Exception {
+		// push from repository1 to repository2
+		PushOperation pop = createPushOperation();
+		try {
+			pop.getOperationResult();
+			fail("Expected Exception not thrown");
+		} catch (IllegalStateException e) {
+			// expected
+		}
+	}
+
+	/**
+	 * We should get an {@link IllegalStateException} if the spec was re-used
+	 *
+	 * @throws Exception
+	 */
+	@Test
+	public void testPushWithReusedSpec() throws Exception {
+
+		PushOperationSpecification spec = new PushOperationSpecification();
+		// the remote is repo2
+		URIish remote = repository2.getUri();
+		// update master upon master
+		List<RemoteRefUpdate> refUpdates = new ArrayList<RemoteRefUpdate>();
+		RemoteRefUpdate update = new RemoteRefUpdate(repository1
+				.getRepository(), "HEAD", "refs/heads/test", false, null, null);
+		refUpdates.add(update);
+		spec.addURIRefUpdates(remote, refUpdates);
+
+		PushOperation pop = new PushOperation(repository1.getRepository(),
+				spec, false, 0);
+		pop.run(null);
+
+		pop = new PushOperation(repository1.getRepository(), spec, false, 0);
+		try {
+			pop.run(null);
+			fail("Expected Exception not thrown");
+		} catch (IllegalStateException e) {
+			// expected
+		}
+	}
+
+	@Test
+	public void testUpdateTrackingBranchIfSpecifiedInRemoteRefUpdate() throws Exception {
+		// Commit on repository 2
+		IProject project = importProject(repository2, projectName);
+		RevCommit commit = repository2.addAndCommit(project, new File(workdir2, "test.txt"), "Commit in repository 2");
+		project.delete(false, false, null);
+
+		// We want to push from repository 2 to 1 (because repository 2 already
+		// has tracking set up)
+		URIish remote = repository1.getUri();
+		String trackingRef = "refs/remotes/origin/master";
+		RemoteRefUpdate update = new RemoteRefUpdate(
+				repository2.getRepository(), "HEAD", "refs/heads/master", false,
+				trackingRef, null);
+		PushOperationSpecification spec = new PushOperationSpecification();
+		spec.addURIRefUpdates(remote, Arrays.asList(update));
+
+		PushOperation push = new PushOperation(repository2.getRepository(),
+				spec, false, 0);
+		push.run(null);
+
+		PushOperationResult result = push.getOperationResult();
+		PushResult pushResult = result.getPushResult(remote);
+		assertNotNull("Expected result to have tracking ref update", pushResult.getTrackingRefUpdate(trackingRef));
+
+		ObjectId trackingId = repository2.getRepository().resolve(trackingRef);
+		assertEquals("Expected tracking branch to be updated", commit.getId(), trackingId);
+	}
+
+	private Status getStatus(PushOperationResult operationResult) {
+		URIish uri = operationResult.getURIs().iterator().next();
+		return operationResult.getPushResult(uri).getRemoteUpdates().iterator()
+				.next().getStatus();
+	}
+
+	private PushOperation createPushOperation() throws Exception {
+		// set up push from repository1 to repository2
+		// we can not re-use the RemoteRefUpdate!!!
+		PushOperationSpecification spec = new PushOperationSpecification();
+		// the remote is repo2
+		URIish remote = new URIish("file:///"
+				+ repository2.getRepository().getDirectory().toString());
+		// update master upon master
+		List<RemoteRefUpdate> refUpdates = new ArrayList<RemoteRefUpdate>();
+		RemoteRefUpdate update = new RemoteRefUpdate(repository1
+				.getRepository(), "HEAD", "refs/heads/test", false, null, null);
+		refUpdates.add(update);
+		spec.addURIRefUpdates(remote, refUpdates);
+		// now we can construct the push operation
+		PushOperation pop = new PushOperation(repository1.getRepository(),
+				spec, false, 0);
+		return pop;
+	}
+
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/RebaseOperationTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/RebaseOperationTest.java
new file mode 100644
index 0000000..ec75cef
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/RebaseOperationTest.java
@@ -0,0 +1,238 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Mathias Kinzler <mathias.kinzler@sap.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.egit.core.internal.op.RebaseOperation;
+import org.eclipse.egit.core.internal.test.GitTestCase;
+import org.eclipse.egit.core.internal.test.TestRepository;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.RebaseResult;
+import org.eclipse.jgit.api.RebaseCommand.Operation;
+import org.eclipse.jgit.api.RebaseResult.Status;
+import org.eclipse.jgit.api.errors.WrongRepositoryStateException;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class RebaseOperationTest extends GitTestCase {
+
+	private static final String TOPIC = Constants.R_HEADS + "topic";
+
+	private static final String MASTER = Constants.R_HEADS + "master";
+
+	TestRepository testRepository;
+
+	Repository repository;
+
+	Git git;
+
+	@Before
+	public void setUp() throws Exception {
+		super.setUp();
+		testRepository = new TestRepository(gitDir);
+		repository = testRepository.getRepository();
+		// create first commit containing a dummy file
+		testRepository
+				.createInitialCommit("testRebaseOperation\n\nfirst commit\n");
+		git = new Git(repository);
+	}
+
+	@Test
+	@Ignore
+	// currently not working as expected; see also TODO in RebaseCommand
+	public void testUpToDate() throws Exception {
+		IFile file = project.createFile("theFile.txt", "Hello, world"
+				.getBytes("UTF-8"));
+		// first commit in master: add theFile.txt
+		RevCommit first = testRepository.addAndCommit(project.project,
+				new File(file.getLocationURI()), "Adding theFile.txt");
+
+		testRepository.createBranch(MASTER, TOPIC);
+
+		// checkout topic
+		testRepository.checkoutBranch(TOPIC);
+
+		file = project.createFile("theSecondFile.txt", "Hello, world"
+				.getBytes("UTF-8"));
+		// topic commit: add second file
+		RevCommit topicCommit = testRepository.addAndCommit(project.project,
+				new File(file.getLocationURI()), "Adding theSecondFile.txt");
+
+		// parent of topic commit should be first master commit before rebase
+		assertEquals(first, topicCommit.getParent(0));
+
+		// rebase topic onto master
+		RebaseOperation op = new RebaseOperation(
+				testRepository.getRepository(), testRepository.getRepository()
+						.getRef(MASTER));
+		op.execute(null);
+
+		RebaseResult res = op.getResult();
+		assertEquals(RebaseResult.Status.UP_TO_DATE, res.getStatus());
+
+		RevCommit newTopic = new RevWalk(repository).parseCommit(repository
+				.resolve(TOPIC));
+		assertEquals(topicCommit, newTopic);
+		assertEquals(first, newTopic.getParent(0));
+	}
+
+	@Test
+	public void testNoConflict() throws Exception {
+		IFile file = project.createFile("theFile.txt", "Hello, world"
+				.getBytes("UTF-8"));
+		// first commit in master: add theFile.txt
+		RevCommit first = testRepository.addAndCommit(project.project,
+				new File(file.getLocationURI()), "Adding theFile.txt");
+
+		testRepository.createBranch(MASTER, TOPIC);
+
+		file.setContents(new ByteArrayInputStream("master".getBytes("UTF-8")),
+				0, null);
+		// second commit in master: modify theFile.txt
+		RevCommit second = git.commit().setAll(true).setMessage(
+				"Modify theFile.txt").call();
+		assertEquals(first, second.getParent(0));
+
+		// checkout topic
+		testRepository.checkoutBranch(TOPIC);
+
+		file = project.createFile("theSecondFile.txt", "Hello, world"
+				.getBytes("UTF-8"));
+		// topic commit: add second file
+		RevCommit topicCommit = testRepository.addAndCommit(project.project,
+				new File(file.getLocationURI()), "Adding theSecondFile.txt");
+
+		// parent of topic commit should be first master commit before rebase
+		assertEquals(first, topicCommit.getParent(0));
+
+		// rebase topic onto master
+		RebaseOperation op = new RebaseOperation(
+				testRepository.getRepository(), testRepository.getRepository()
+						.getRef(MASTER));
+		op.execute(null);
+
+		RebaseResult res = op.getResult();
+		assertEquals(RebaseResult.Status.OK, res.getStatus());
+
+		RevCommit newTopic = new RevWalk(repository).parseCommit(repository
+				.resolve(TOPIC));
+		assertEquals(second, newTopic.getParent(0));
+	}
+
+	@Test
+	public void testStopAndAbortOnConflict() throws Exception {
+		IFile file = project.createFile("theFile.txt", "Hello, world"
+				.getBytes("UTF-8"));
+		// first commit in master: add theFile.txt
+		RevCommit first = testRepository.addAndCommit(project.project,
+				new File(file.getLocationURI()), "Adding theFile.txt");
+
+		testRepository.createBranch(MASTER, TOPIC);
+
+		file.setContents(new ByteArrayInputStream("master".getBytes("UTF-8")),
+				0, null);
+		// second commit in master: modify theFile.txt
+		RevCommit second = git.commit().setAll(true).setMessage(
+				"Modify theFile.txt").call();
+		assertEquals(first, second.getParent(0));
+
+		// checkout topic
+		testRepository.checkoutBranch(TOPIC);
+
+		// set conflicting content in topic
+		file.setContents(new ByteArrayInputStream("topic".getBytes("UTF-8")),
+				0, null);
+		// topic commit: add second file
+		RevCommit topicCommit = testRepository.addAndCommit(project.project,
+				new File(file.getLocationURI()), "Changing theFile.txt again");
+
+		// parent of topic commit should be first master commit before rebase
+		assertEquals(first, topicCommit.getParent(0));
+
+		// rebase topic onto master
+		RebaseOperation op = new RebaseOperation(
+				testRepository.getRepository(), testRepository.getRepository()
+						.getRef(MASTER));
+		op.execute(null);
+
+		RebaseResult res = op.getResult();
+		assertEquals(RebaseResult.Status.STOPPED, res.getStatus());
+
+		// let's try to abort this here
+		RebaseOperation abort = new RebaseOperation(repository, Operation.ABORT);
+		abort.execute(null);
+		RebaseResult abortResult = abort.getResult();
+		assertEquals(Status.ABORTED, abortResult.getStatus());
+
+		assertEquals(topicCommit, repository.resolve(Constants.HEAD));
+	}
+
+	@Test
+	public void testExceptionWhenRestartingStoppedRebase() throws Exception {
+		IFile file = project.createFile("theFile.txt", "Hello, world"
+				.getBytes("UTF-8"));
+		// first commit in master: add theFile.txt
+		RevCommit first = testRepository.addAndCommit(project.project,
+				new File(file.getLocationURI()), "Adding theFile.txt");
+
+		testRepository.createBranch(MASTER, TOPIC);
+
+		file.setContents(new ByteArrayInputStream("master".getBytes("UTF-8")),
+				0, null);
+		// second commit in master: modify theFile.txt
+		RevCommit second = git.commit().setAll(true).setMessage(
+				"Modify theFile.txt").call();
+		assertEquals(first, second.getParent(0));
+
+		// checkout topic
+		testRepository.checkoutBranch(TOPIC);
+
+		// set conflicting content in topic
+		file.setContents(new ByteArrayInputStream("topic".getBytes("UTF-8")),
+				0, null);
+		// topic commit: add second file
+		RevCommit topicCommit = testRepository.addAndCommit(project.project,
+				new File(file.getLocationURI()), "Changing theFile.txt again");
+
+		// parent of topic commit should be first master commit before rebase
+		assertEquals(first, topicCommit.getParent(0));
+
+		// rebase topic onto master
+		RebaseOperation op = new RebaseOperation(repository, repository
+				.getRef(MASTER));
+		op.execute(null);
+
+		RebaseResult res = op.getResult();
+		assertEquals(RebaseResult.Status.STOPPED, res.getStatus());
+
+		try {
+			// let's try to start again, we should get a wrapped
+			// WrongRepositoryStateException
+			op = new RebaseOperation(repository, repository.getRef(MASTER));
+			op.execute(null);
+			fail("Expected Exception not thrown");
+		} catch (CoreException e) {
+			Throwable cause = e.getCause();
+			assertTrue(cause instanceof WrongRepositoryStateException);
+		}
+	}
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/RemoveFromIndexOperationTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/RemoveFromIndexOperationTest.java
new file mode 100644
index 0000000..aac995c
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/RemoveFromIndexOperationTest.java
@@ -0,0 +1,221 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Stefan Lay <stefan.lay@sap.com>
+ * Copyright (C) 2011, Dariusz Luksza <dariusz@luksza.org>
+ * Copyright (C) 2012, Robin Stocker <robin@nibor.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import static java.util.Arrays.asList;
+import static junit.framework.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.egit.core.internal.op.AddToIndexOperation;
+import org.eclipse.egit.core.internal.op.RemoveFromIndexOperation;
+import org.eclipse.egit.core.internal.test.GitTestCase;
+import org.eclipse.egit.core.internal.test.TestProject;
+import org.eclipse.egit.core.internal.test.TestRepository;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.util.FileUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+// based on AddOperationTest
+public class RemoveFromIndexOperationTest extends GitTestCase {
+
+	private TestRepository testRepo;
+
+	private File gitDir2;
+	private TestRepository testRepo2;
+	private TestProject project2;
+
+	@Before
+	public void setUp() throws Exception {
+		super.setUp();
+		gitDir = new File(project.getProject()
+				.getLocationURI().getPath(), Constants.DOT_GIT);
+		testRepo = new TestRepository(gitDir);
+		testRepo.connect(project.getProject());
+		testRepo.commit("initial commit");
+
+		project2 = new TestProject(true, "Project-2");
+		gitDir2 = new File(project2.getProject()
+				.getLocationURI().getPath(), Constants.DOT_GIT);
+		testRepo2 = new TestRepository(gitDir2);
+		testRepo2.connect(project2.getProject());
+		testRepo2.commit("initial commit repo 2");
+	}
+
+	@After
+	public void tearDown() throws Exception {
+		testRepo.dispose();
+		testRepo2.dispose();
+		project2.dispose();
+		if (gitDir2.exists())
+			FileUtils.delete(gitDir2, FileUtils.RECURSIVE | FileUtils.RETRY);
+		super.tearDown();
+	}
+
+	@Test
+	public void shouldUnTrackFile() throws Exception {
+		// given
+		IFile file1 = createFileInRepo("a.txt");
+		new AddToIndexOperation(asList(file1)).execute(null);
+
+		// when
+		new RemoveFromIndexOperation(Arrays.asList(file1.getLocation())).execute(null);
+
+		// then
+		assertTrue(testRepo.removedFromIndex(file1.getLocation()
+				.toPortableString()));
+	}
+
+	@Test
+	public void shouldUnTrackFilesInFolder() throws Exception {
+		// given
+		IFile file1 = createFileInRepo("sub/a.txt");
+		IFile file2 = createFileInRepo("sub/b.txt");
+		IFolder container = project.getProject().getFolder("sub");
+		new AddToIndexOperation(asList(file1, file2)).execute(null);
+
+		// when
+		new RemoveFromIndexOperation(asList(container.getLocation())).execute(null);
+
+		// then
+		assertTrue(testRepo.removedFromIndex(file1.getLocation().toPortableString()));
+		assertTrue(testRepo.removedFromIndex(file2.getLocation().toPortableString()));
+	}
+
+	@Test
+	public void shouldUnstExistingFile() throws Exception {
+		// given
+		IFile file1 = createFileInRepo("a.txt");
+		new AddToIndexOperation(asList(file1)).execute(null);
+
+		testRepo.commit("first commit");
+
+		Thread.sleep(1000);
+		file1.setContents(
+				new ByteArrayInputStream("other text".getBytes(project.project
+						.getDefaultCharset())), 0, null);
+		new AddToIndexOperation(asList(file1)).execute(null);
+
+		// when
+		new RemoveFromIndexOperation(asList(file1.getLocation())).execute(null);
+
+		// then
+		assertTrue(testRepo.removedFromIndex(file1.getLocation().toPortableString()));
+	}
+
+	@Test
+	public void shouldUnstageFilesInFolder() throws Exception {
+		// given
+		IFile file1 = createFileInRepo("sub/a.txt");
+		IFile file2 = createFileInRepo("sub/b.txt");
+		IFolder container = project.getProject().getFolder("sub");
+		List<IFolder> addResources = asList(project.getProject().getFolder("sub"));
+		new AddToIndexOperation(addResources).execute(null);
+
+		testRepo.commit("first commit");
+
+		Thread.sleep(1000);
+
+		file1.setContents(
+				new ByteArrayInputStream("other text".getBytes(project.project
+						.getDefaultCharset())), 0, null);
+		file2.setContents(
+				new ByteArrayInputStream("other text".getBytes(project.project
+						.getDefaultCharset())), 0, null);
+		new AddToIndexOperation(addResources).execute(null);
+
+		// when
+		new RemoveFromIndexOperation(asList(container.getLocation())).execute(null);
+
+		// then
+		assertTrue(testRepo.removedFromIndex(file1.getLocation().toPortableString()));
+		assertTrue(testRepo.removedFromIndex(file2.getLocation().toPortableString()));
+	}
+
+	@Test
+	public void shouldUnstageFilesInNestedFolder() throws Exception {
+		// given
+		IFile file1 = createFileInRepo("sub/next/a.txt");
+		IFile file2 = createFileInRepo("sub/next/b.txt");
+		IFolder container = project.getProject().getFolder("sub");
+		List<IFolder> addResources = asList(project.getProject().getFolder("sub"));
+		new AddToIndexOperation(addResources).execute(null);
+
+		testRepo.commit("first commit");
+
+		Thread.sleep(1000);
+
+		file1.setContents(
+				new ByteArrayInputStream("other text".getBytes(project.project
+						.getDefaultCharset())), 0, null);
+		file2.setContents(
+				new ByteArrayInputStream("other text".getBytes(project.project
+						.getDefaultCharset())), 0, null);
+		new AddToIndexOperation(addResources).execute(null);
+
+		// when
+		new RemoveFromIndexOperation(asList(container.getLocation())).execute(null);
+
+		// then
+		assertTrue(testRepo.removedFromIndex(file1.getLocation().toPortableString()));
+		assertTrue(testRepo.removedFromIndex(file2.getLocation().toPortableString()));
+	}
+
+	@Test
+	public void shouldUnstageFilesFromMultipleRepositories() throws Exception {
+		// given
+		IFile fileRepo1 = testUtils.addFileToProject(project.getProject(), "1.txt", "content");
+		IFile fileRepo2 = testUtils.addFileToProject(project2.getProject(), "2.txt", "content");
+		new AddToIndexOperation(asList(fileRepo1)).execute(null);
+		new AddToIndexOperation(asList(fileRepo2)).execute(null);
+
+		// when
+		new RemoveFromIndexOperation(Arrays.asList(fileRepo1.getLocation(), fileRepo2.getLocation())).execute(null);
+
+		// then
+		assertTrue(testRepo.removedFromIndex(fileRepo1.getLocation()
+				.toPortableString()));
+		assertTrue(testRepo.removedFromIndex(fileRepo2.getLocation()
+				.toPortableString()));
+	}
+
+	@Test
+	public void shouldRemoveFromIndexOnInitialCommit() throws Exception {
+		testRepo.dispose();
+		FileUtils.delete(gitDir, FileUtils.RECURSIVE | FileUtils.RETRY);
+		testRepo = new TestRepository(gitDir);
+		testRepo.connect(project.getProject());
+
+		IFile file = testUtils.addFileToProject(project.getProject(), "file.txt", "content");
+		new AddToIndexOperation(asList(file)).execute(null);
+
+		assertTrue(testRepo.inIndex(file.getLocation().toString()));
+
+		new RemoveFromIndexOperation(Arrays.asList(file.getLocation())).execute(null);
+
+		assertFalse(testRepo.inIndex(file.getLocation().toString()));
+		assertTrue(file.getLocation().toFile().exists());
+	}
+
+	private IFile createFileInRepo(String fileName) throws Exception {
+		return testUtils.addFileToProject(project.getProject(), fileName,
+				"some text");
+	}
+
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/ResetOperationTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/ResetOperationTest.java
new file mode 100644
index 0000000..54caf73
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/ResetOperationTest.java
@@ -0,0 +1,155 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Jens Baumgart <jens.baumgart@sap.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.InputStream;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.egit.core.internal.op.ResetOperation;
+import org.eclipse.egit.core.internal.test.GitTestCase;
+import org.eclipse.egit.core.internal.test.TestRepository;
+import org.eclipse.jgit.api.ResetCommand.ResetType;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ResetOperationTest extends GitTestCase {
+
+	TestRepository testRepository;
+
+	Repository repository;
+
+	// members filled by setupRepository()
+	RevCommit initialCommit;
+
+	File projectFile;
+
+	IFile untrackedFile;
+
+	IFile fileInIndex;
+
+	@Before
+	public void setUp() throws Exception {
+		super.setUp();
+		testRepository = new TestRepository(gitDir);
+		repository = testRepository.getRepository();
+	}
+
+	@After
+	public void tearDown() throws Exception {
+		testRepository.dispose();
+		repository = null;
+		super.tearDown();
+	}
+
+	@Test
+	public void testHardReset() throws Exception {
+		setupRepository();
+		String fileInIndexPath = fileInIndex.getLocation().toPortableString();
+		new ResetOperation(repository, initialCommit.getName(), ResetType.HARD)
+				.execute(null);
+		// .project must disappear, related Eclipse project must be deleted
+		assertFalse(projectFile.exists());
+		assertFalse(project.getProject().exists());
+		// check if HEAD points to initial commit now
+		assertTrue(repository.resolve("HEAD").equals(initialCommit));
+		// check if files were removed
+		assertFalse(untrackedFile.exists());
+		assertFalse(fileInIndex.exists());
+		// fileInIndex must no longer be in HEAD and in the index
+		assertFalse(testRepository.inHead(fileInIndexPath));
+		assertFalse(testRepository.inIndex(fileInIndexPath));
+	}
+
+	@Test
+	public void testSoftReset() throws Exception {
+		setupRepository();
+		String fileInIndexPath = fileInIndex.getLocation().toPortableString();
+		new ResetOperation(repository, initialCommit.getName(), ResetType.SOFT)
+				.execute(null);
+		// .project must remain
+		assertTrue(projectFile.exists());
+		assertTrue(project.getProject().exists());
+		// check if HEAD points to initial commit now
+		assertTrue(repository.resolve("HEAD").equals(initialCommit));
+		// untrackedFile and fileInIndex must still exist
+		assertTrue(untrackedFile.exists());
+		assertTrue(fileInIndex.exists());
+		// fileInIndex must no longer be in HEAD
+		assertFalse(testRepository.inHead(fileInIndexPath));
+		// fileInIndex must exist in the index
+		assertTrue(testRepository.inIndex(fileInIndexPath));
+	}
+
+	@Test
+	public void testMixedReset() throws Exception {
+		setupRepository();
+		String fileInIndexPath = fileInIndex.getLocation().toPortableString();
+		new ResetOperation(repository, initialCommit.getName(), ResetType.MIXED)
+				.execute(null);
+		// .project must remain
+		assertTrue(projectFile.exists());
+		assertTrue(project.getProject().exists());
+		// check if HEAD points to initial commit now
+		assertTrue(repository.resolve("HEAD").equals(initialCommit));
+		// untrackedFile and fileInIndex must still exist
+		assertTrue(untrackedFile.exists());
+		assertTrue(fileInIndex.exists());
+		// fileInIndex must no longer be in HEAD
+		assertFalse(testRepository.inHead(fileInIndexPath));
+		// fileInIndex must not in the index
+		assertFalse(testRepository.inIndex(fileInIndexPath));
+	}
+
+	private void setupRepository() throws Exception {
+		// create first commit containing a dummy file
+		initialCommit = testRepository
+				.createInitialCommit("testResetOperation\n\nfirst commit\n");
+		// add .project to version control
+		String path = project.getProject().getLocation().append(".project")
+				.toOSString();
+		projectFile = new File(path);
+		testRepository.track(projectFile);
+		// add fileInIndex to version control
+		fileInIndex = createFile("fileInIndex");
+		testRepository.track(new File(fileInIndex.getLocation().toOSString()));
+		testRepository.commit("Add .project file");
+		// modify fileInIndex and add it to the index
+		InputStream stream = new ByteArrayInputStream(new byte[] { 'I', 'n',
+				'd', 'e', 'x' });
+		fileInIndex.setContents(stream, 0, null);
+		testRepository.addToIndex(fileInIndex);
+		// create an untracked file
+		untrackedFile = createFile("untrackedFile");
+	}
+
+	/**
+	 * create a file with the given name in the root folder of testproject
+	 *
+	 * @param name
+	 *            name of file
+	 * @return new file
+	 * @throws CoreException
+	 */
+	private IFile createFile(String name) throws CoreException {
+		IFile file = project.project.getFile(name);
+		file.create(
+				new ByteArrayInputStream(new byte[] { 'T', 'e', 's', 't' }),
+				true, null);
+		return file;
+	}
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/StashCreateOperationTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/StashCreateOperationTest.java
new file mode 100644
index 0000000..5df7b90
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/StashCreateOperationTest.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (C) 2012, Maik Schreiber <blizzy@blizzy.de>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.egit.core.internal.op;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+
+import org.eclipse.egit.core.internal.op.StashCreateOperation;
+import org.eclipse.egit.core.internal.test.GitTestCase;
+import org.eclipse.egit.core.internal.test.TestRepository;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class StashCreateOperationTest extends GitTestCase {
+
+	TestRepository testRepository;
+
+	Repository repository;
+
+	@Before
+	public void setUp() throws Exception {
+		super.setUp();
+		gitDir = new File(project.getProject()
+				.getLocationURI().getPath(), Constants.DOT_GIT);
+		testRepository = new TestRepository(gitDir);
+		repository = testRepository.getRepository();
+		testRepository.connect(project.getProject());
+		testRepository.commit("initial commit");
+	}
+
+	@After
+	public void tearDown() throws Exception {
+		testRepository.dispose();
+		repository = null;
+		super.tearDown();
+	}
+
+	@Test
+	public void testDefaultMessage() throws Exception {
+		testUtils.addFileToProject(project.getProject(), "foo/a.txt", "some text");
+		StashCreateOperation stashCreateOperation = new StashCreateOperation(repository);
+		stashCreateOperation.execute(null);
+
+		RevWalk revWalk = new RevWalk(repository);
+		RevCommit commit = revWalk.parseCommit(repository.resolve("stash@{0}"));
+		assertTrue(commit.getFullMessage().length() > 0);
+	}
+
+	@Test
+	public void testCustomMessage() throws Exception {
+		testUtils.addFileToProject(project.getProject(), "foo/a.txt", "some text");
+		String message = "stash message";
+		StashCreateOperation stashCreateOperation = new StashCreateOperation(repository, message);
+		stashCreateOperation.execute(null);
+
+		RevWalk revWalk = new RevWalk(repository);
+		RevCommit commit = revWalk.parseCommit(repository.resolve("stash@{0}"));
+		assertEquals(message, commit.getFullMessage());
+	}
+
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/TagOperationTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/TagOperationTest.java
new file mode 100644
index 0000000..c1b1494
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/TagOperationTest.java
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ * Copyright (C) 2010, 2012 Chris Aniszczyk <caniszczyk@gmail.com> and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.egit.core.internal.op.TagOperation;
+import org.eclipse.egit.core.internal.test.DualRepositoryTestCase;
+import org.eclipse.egit.core.internal.test.TestRepository;
+import org.eclipse.egit.core.internal.test.TestUtils;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.TagBuilder;
+import org.eclipse.jgit.revwalk.RevTag;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.util.RawParseUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TagOperationTest extends DualRepositoryTestCase {
+
+	File workdir;
+
+	String projectName = "TagTest";
+
+	IProject project;
+
+	@Before
+	public void setUp() throws Exception {
+
+		workdir = testUtils.createTempDir("Repository1");
+
+		repository1 = new TestRepository(new File(workdir, Constants.DOT_GIT));
+
+		project = testUtils.createProjectInLocalFileSystem(workdir,
+				projectName);
+		testUtils.addFileToProject(project, "folder1/file1.txt", "Hello world");
+
+		repository1.connect(project);
+		repository1.trackAllFiles(project);
+		repository1.commit("Initial commit");
+	}
+
+	@After
+	public void tearDown() throws Exception {
+		project.close(null);
+		project.delete(false, false, null);
+		repository1.dispose();
+		repository1 = null;
+		testUtils.deleteTempDirs();
+	}
+
+	@Test
+	public void addTag() throws Exception {
+		assertTrue("Tags should be empty", repository1.getRepository()
+				.getTags().isEmpty());
+		TagBuilder newTag = new TagBuilder();
+		newTag.setTag("TheNewTag");
+		newTag.setMessage("Well, I'm the tag");
+		newTag.setTagger(RawParseUtils.parsePersonIdent(TestUtils.AUTHOR));
+		newTag.setObjectId(repository1.getRepository()
+				.resolve("refs/heads/master"), Constants.OBJ_COMMIT);
+		TagOperation top = new TagOperation(repository1.getRepository(),
+				newTag, false);
+		top.execute(new NullProgressMonitor());
+		assertFalse("Tags should not be empty", repository1.getRepository()
+				.getTags().isEmpty());
+
+		try {
+			top.execute(null);
+			fail("Expected Exception not thrown");
+		} catch (CoreException e) {
+			// expected
+		}
+
+		top = new TagOperation(repository1.getRepository(), newTag, true);
+		try {
+			top.execute(null);
+			fail("Expected Exception not thrown");
+		} catch (CoreException e) {
+			// expected
+		}
+		Ref tagRef = repository1.getRepository().getTags().get("TheNewTag");
+		RevWalk walk = new RevWalk(repository1.getRepository());
+		RevTag tag = walk.parseTag(
+				repository1.getRepository().resolve(tagRef.getName()));
+
+		newTag.setMessage("Another message");
+		assertFalse("Messages should differ", tag.getFullMessage().equals(
+				newTag.getMessage()));
+		top.execute(null);
+		tag = walk.parseTag(
+				repository1.getRepository().resolve(tagRef.getName()));
+		assertTrue("Messages be same", tag.getFullMessage().equals(
+				newTag.getMessage()));
+	}
+
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/TrackUntrackOperationTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/TrackUntrackOperationTest.java
new file mode 100644
index 0000000..eab08ed
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/op/TrackUntrackOperationTest.java
@@ -0,0 +1,141 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Mathias Kinzler <mathias.kinzler@sap.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import static org.junit.Assert.assertEquals;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceVisitor;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.egit.core.internal.op.AddToIndexOperation;
+import org.eclipse.egit.core.internal.op.UntrackOperation;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.egit.core.internal.test.DualRepositoryTestCase;
+import org.eclipse.egit.core.internal.test.TestRepository;
+import org.eclipse.jgit.dircache.DirCache;
+import org.eclipse.jgit.lib.Constants;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TrackUntrackOperationTest extends DualRepositoryTestCase {
+
+	File workdir;
+
+	IProject project;
+
+	String projectName = "TrackTest";
+
+	@Before
+	public void setUp() throws Exception {
+
+		workdir = testUtils.createTempDir("Repository1");
+
+		repository1 = new TestRepository(new File(workdir, Constants.DOT_GIT));
+
+		// now we create a project in repo1
+		project = testUtils
+				.createProjectInLocalFileSystem(workdir, projectName);
+		testUtils.addFileToProject(project, "folder1/file1.txt", "Hello world");
+
+		repository1.connect(project);
+	}
+
+	@After
+	public void tearDown() throws Exception {
+		project.close(null);
+		project.delete(false, false, null);
+		repository1.dispose();
+		repository1 = null;
+		testUtils.deleteTempDirs();
+	}
+
+	@Test
+	public void testTrackFiles() throws Exception {
+
+		final ArrayList<IFile> files = new ArrayList<IFile>();
+
+		project.accept(new IResourceVisitor() {
+
+			public boolean visit(IResource resource) throws CoreException {
+				if (resource instanceof IFile)
+					files.add((IFile) resource);
+				return true;
+			}
+		});
+
+		IFile[] fileArr = files.toArray(new IFile[files.size()]);
+
+		assertTrackedState(fileArr, false);
+
+		AddToIndexOperation trop = new AddToIndexOperation(files);
+		trop.execute(new NullProgressMonitor());
+
+		assertTrackedState(fileArr, true);
+
+		UntrackOperation utop = new UntrackOperation(Arrays.asList(fileArr));
+
+		utop.execute(new NullProgressMonitor());
+
+		assertTrackedState(fileArr, false);
+	}
+
+	@SuppressWarnings("boxing")
+	private void assertTrackedState(IFile[] fileArr, boolean expectedState)
+			throws IOException {
+		DirCache cache = repository1.getRepository().readDirCache();
+		for (IFile file : fileArr) {
+			RepositoryMapping rm = RepositoryMapping.getMapping(file);
+			String fileDir = rm.getRepoRelativePath(file);
+			boolean tracked = cache.findEntry(fileDir) > -1;
+			assertEquals("Wrong tracking state", expectedState, tracked);
+		}
+	}
+
+	@Test
+	public void testTrackProject() throws Exception {
+
+		final ArrayList<IContainer> containers = new ArrayList<IContainer>();
+		containers.add(project);
+
+		final ArrayList<IFile> files = new ArrayList<IFile>();
+
+		project.accept(new IResourceVisitor() {
+
+			public boolean visit(IResource resource) throws CoreException {
+				if (resource instanceof IFile)
+					files.add((IFile) resource);
+				return true;
+			}
+		});
+
+		IFile[] fileArr = files.toArray(new IFile[files.size()]);
+
+		assertTrackedState(fileArr, false);
+
+		AddToIndexOperation trop = new AddToIndexOperation(containers);
+		trop.execute(new NullProgressMonitor());
+
+		assertTrackedState(fileArr, true);
+
+		UntrackOperation utrop = new UntrackOperation(containers);
+		utrop.execute(new NullProgressMonitor());
+
+		assertTrackedState(fileArr, false);
+	}
+
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/project/RepositoryMappingTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/project/RepositoryMappingTest.java
new file mode 100644
index 0000000..29566a9
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/project/RepositoryMappingTest.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright (C) 2012, 2013 Robin Stocker <robin@nibor.org> and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.project;
+
+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 org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.egit.core.internal.test.GitTestCase;
+import org.eclipse.egit.core.internal.test.TestRepository;
+import org.eclipse.jgit.lib.Repository;
+import org.junit.Before;
+import org.junit.Test;
+
+public class RepositoryMappingTest extends GitTestCase {
+
+	private Repository repository;
+
+	@Before
+	@Override
+	public void setUp() throws Exception {
+		super.setUp();
+
+		TestRepository testRepo = new TestRepository(gitDir);
+		testRepo.connect(project.project);
+		repository = testRepo.getRepository();
+	}
+
+	@Test
+	public void shouldReturnMappingForResourceInProject() throws Exception {
+		IFile file = project.createFile("inproject.txt", new byte[] {});
+
+		RepositoryMapping mapping = RepositoryMapping.getMapping(file);
+
+		assertNotNull(mapping);
+		assertEquals(repository, mapping.getRepository());
+		assertEquals(project.getProject(), mapping.getContainer());
+		assertEquals(project.getProject().getName() + "/inproject.txt", mapping.getRepoRelativePath(file));
+	}
+
+	@Test
+	public void shouldNotReturnMappingForResourceOutsideOfProject() {
+		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+		IPath filePath = getWorkTreePath().append("outside.txt");
+		IFile file = root.getFile(filePath);
+		assertFalse(file.exists());
+
+		RepositoryMapping mapping = RepositoryMapping.getMapping(file);
+
+		assertNull(mapping);
+	}
+
+	@Test
+	public void shouldReturnMappingForPathOutsideOfProject() {
+		IPath filePath = getWorkTreePath().append("outside.txt");
+
+		RepositoryMapping mapping = RepositoryMapping.getMapping(filePath);
+
+		assertNotNull(mapping);
+		assertEquals(repository, mapping.getRepository());
+		assertEquals("outside.txt", mapping.getRepoRelativePath(filePath));
+	}
+
+	@Test
+	public void shouldReturnMappingWhenPathIsRepository() {
+		IPath workTreePath = getWorkTreePath();
+
+		RepositoryMapping mapping = RepositoryMapping.getMapping(workTreePath);
+
+		assertNotNull(mapping);
+		assertEquals(repository, mapping.getRepository());
+		assertEquals("", mapping.getRepoRelativePath(workTreePath));
+	}
+
+	@Test
+	public void shouldNotReturnMappingWhenPathIsOutsideRepository() {
+		IPath workTreePath = getWorkTreePath();
+
+		assertNull(RepositoryMapping
+				.getMapping(new Path("D:/some/made/up/path")));
+		assertNull(RepositoryMapping.getMapping(new Path("/some/made/up/path")));
+		assertNull(RepositoryMapping.getMapping(new Path(
+				"/thereshouldnever/be/something/here")));
+
+		if (workTreePath.getDevice() == null)
+			assertNull(RepositoryMapping.getMapping(workTreePath
+					.setDevice("C:")));
+	}
+
+	@Test
+	public void shouldFindRepositoryMappingForRepository() {
+		RepositoryMapping mapping = RepositoryMapping.findRepositoryMapping(repository);
+
+		assertNotNull(mapping);
+		assertEquals(repository, mapping.getRepository());
+	}
+
+	private IPath getWorkTreePath() {
+		return new Path(repository.getWorkTree().getAbsolutePath());
+	}
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/securestorage/EGitSecureStoreTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/securestorage/EGitSecureStoreTest.java
new file mode 100644
index 0000000..7619494
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/securestorage/EGitSecureStoreTest.java
@@ -0,0 +1,217 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Jens Baumgart <jens.baumgart@sap.com>
+ * Copyright (C) 2010, Edwin Kempin <edwin.kempin@sap.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.securestorage;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.HashMap;
+
+import javax.crypto.spec.PBEKeySpec;
+
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.egit.core.internal.securestorage.EGitSecureStore;
+import org.eclipse.egit.core.internal.securestorage.UserPasswordCredentials;
+import org.eclipse.equinox.security.storage.ISecurePreferences;
+import org.eclipse.equinox.security.storage.SecurePreferencesFactory;
+import org.eclipse.equinox.security.storage.provider.IProviderHints;
+import org.eclipse.jgit.transport.URIish;
+import org.eclipse.jgit.util.FileUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class EGitSecureStoreTest {
+
+	ISecurePreferences secureStoreForTest;
+
+	EGitSecureStore store;
+
+	@Before
+	public void setUp() throws Exception {
+		setupNewSecureStore();
+		store = new EGitSecureStore(secureStoreForTest);
+	}
+
+	@After
+	public void tearDown() throws Exception {
+		secureStoreForTest.flush();
+	}
+
+	@Test
+	public void testPutUserAndPassword() throws Exception {
+		URIish uri = new URIish("http://testRepo.example.com/testrepo");
+		UserPasswordCredentials credentials = new UserPasswordCredentials(
+				"agitter", "letmein");
+		store.putCredentials(uri, credentials);
+
+		ISecurePreferences node = secureStoreForTest.node(EGitSecureStore
+				.calcNodePath(uri).toString());
+		assertEquals("agitter", node.get("user", null));
+		assertTrue(node.isEncrypted("password"));
+		assertEquals("letmein", node.get("password", null));
+	}
+
+	@Test
+	public void testGetUserAndPassword() throws Exception {
+		URIish uri = new URIish("http://testRepo.example.com/testrepo");
+		UserPasswordCredentials credentials = new UserPasswordCredentials(
+				"agitter", "letmein");
+		store.putCredentials(uri, credentials);
+
+		UserPasswordCredentials storedCredentials = store.getCredentials(uri);
+		assertEquals("agitter", storedCredentials.getUser());
+		assertEquals("letmein", storedCredentials.getPassword());
+	}
+
+	@Test
+	public void testGetUserAndPasswordUnknownURI() throws Exception {
+		URIish uri = new URIish("http://testRepo.example.com/testrepo");
+
+		UserPasswordCredentials storedCredentials = store.getCredentials(uri);
+		assertNull(storedCredentials);
+	}
+
+	@Test
+	public void testPutUserAndPasswordURIContainingUserAndPass()
+			throws Exception {
+		URIish uri = new URIish(
+				"http://user:pass@testRepo.example.com/testrepo");
+		UserPasswordCredentials credentials = new UserPasswordCredentials(
+				"agitter", "letmein");
+		store.putCredentials(uri, credentials);
+
+		ISecurePreferences node = secureStoreForTest.node(EGitSecureStore
+				.calcNodePath(uri).toString());
+		assertEquals("agitter", node.get("user", null));
+		assertTrue(node.isEncrypted("password"));
+		assertEquals("letmein", node.get("password", null));
+	}
+
+	@Test
+	public void testGetUserAndPasswordURIContainingUserAndPass()
+			throws Exception {
+		store.putCredentials(
+				new URIish("http://testRepo.example.com/testrepo"),
+				new UserPasswordCredentials("agitter", "letmein"));
+		UserPasswordCredentials credentials = store.getCredentials(new URIish(
+				"http://agitter:letmein@testRepo.example.com/testrepo"));
+		assertEquals("agitter", credentials.getUser());
+		assertEquals("letmein", credentials.getPassword());
+	}
+
+	@Test
+	public void testGetUserAndPasswordURIContainingOtherUserAndPass()
+			throws Exception {
+		store.putCredentials(
+				new URIish("http://testRepo.example.com/testrepo"),
+				new UserPasswordCredentials("agitter", "letmein"));
+		assertNull(store.getCredentials(new URIish(
+				"http://otheruser:otherpass@testRepo.example.com/testrepo")));
+	}
+
+	@Test
+	public void testClearCredentials() throws Exception {
+		URIish uri = new URIish("http://testRepo.example.com/testrepo");
+		UserPasswordCredentials credentials = new UserPasswordCredentials(
+				"agitter", "letmein");
+		store.putCredentials(uri, credentials);
+		store.clearCredentials(uri);
+		assertEquals(null, store.getCredentials(uri));
+	}
+
+	@Test
+	public void testEnsureDefaultPortHttp() throws Exception {
+		URIish uri = new URIish("http://testRepo.example.com/testrepo");
+		UserPasswordCredentials credentials = new UserPasswordCredentials(
+				"agitter", "letmein");
+		store.putCredentials(uri, credentials);
+		URIish uri2 = new URIish("http://testRepo.example.com:80/testrepo");
+		assertEquals(credentials.getUser(), store.getCredentials(uri2).getUser());
+		assertEquals(credentials.getPassword(), store.getCredentials(uri2).getPassword());
+	}
+
+	@Test
+	public void testEnsureDefaultPortHttps() throws Exception {
+		URIish uri = new URIish("https://testRepo.example.com/testrepo");
+		UserPasswordCredentials credentials = new UserPasswordCredentials(
+				"agitter", "letmein");
+		store.putCredentials(uri, credentials);
+		URIish uri2 = new URIish("https://testRepo.example.com:443/testrepo");
+		assertEquals(credentials.getUser(), store.getCredentials(uri2).getUser());
+		assertEquals(credentials.getPassword(), store.getCredentials(uri2).getPassword());
+	}
+
+	@Test
+	public void testEnsureDefaultPortSftp() throws Exception {
+		URIish uri = new URIish("sftp://testRepo.example.com/testrepo");
+		UserPasswordCredentials credentials = new UserPasswordCredentials(
+				"agitter", "letmein");
+		store.putCredentials(uri, credentials);
+		URIish uri2 = new URIish("sftp://testRepo.example.com:22/testrepo");
+		assertEquals(credentials.getUser(), store.getCredentials(uri2).getUser());
+		assertEquals(credentials.getPassword(), store.getCredentials(uri2).getPassword());
+	}
+
+	@Test
+	public void testEnsureDefaultPortFtp() throws Exception {
+		URIish uri = new URIish("ftp://testRepo.example.com/testrepo");
+		UserPasswordCredentials credentials = new UserPasswordCredentials(
+				"agitter", "letmein");
+		store.putCredentials(uri, credentials);
+		URIish uri2 = new URIish("ftp://testRepo.example.com:21/testrepo");
+		assertEquals(credentials.getUser(), store.getCredentials(uri2).getUser());
+		assertEquals(credentials.getPassword(), store.getCredentials(uri2).getPassword());
+	}
+
+	@Test
+	public void testEnsureDefaultPortSsh() throws Exception {
+		URIish uri = new URIish("ssh://agitter@testRepo.example.com/testrepo");
+		UserPasswordCredentials credentials = new UserPasswordCredentials(
+				"agitter", "letmein");
+		store.putCredentials(uri, credentials);
+		URIish uri2 = new URIish("ssh://testRepo.example.com:22/testrepo");
+		assertEquals(credentials.getUser(), store.getCredentials(uri2).getUser());
+		assertEquals(credentials.getPassword(), store.getCredentials(uri2).getPassword());
+	}
+
+	@Test
+	public void testClearCredentialsTwice() throws Exception {
+		URIish uri = new URIish("http://testRepo.example.com/testrepo");
+		UserPasswordCredentials credentials = new UserPasswordCredentials(
+				"agitter", "letmein");
+		store.putCredentials(uri, credentials);
+		store.clearCredentials(uri);
+		assertEquals(null, store.getCredentials(uri));
+		store.clearCredentials(uri);
+		assertEquals(null, store.getCredentials(uri));
+	}
+
+	private void setupNewSecureStore() throws IOException,
+			MalformedURLException {
+		HashMap<String, Object> options = new HashMap<String, Object>();
+		options.put(IProviderHints.DEFAULT_PASSWORD, new PBEKeySpec(
+				"masterpass".toCharArray()));
+		String secureStorePath = ResourcesPlugin.getWorkspace().getRoot()
+				.getLocation().append("testSecureStore").toOSString();
+		File file = new File(secureStorePath);
+		if (file.exists())
+			FileUtils.delete(file, FileUtils.RECURSIVE | FileUtils.RETRY);
+		URL url = file.toURI().toURL();
+		secureStoreForTest = SecurePreferencesFactory.open(url, options);
+		secureStoreForTest.node("/GIT").removeNode();
+	}
+
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/storage/BlobStorageTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/storage/BlobStorageTest.java
index cc69dd0..472ebfa 100644
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/storage/BlobStorageTest.java
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/storage/BlobStorageTest.java
@@ -22,11 +22,11 @@
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.op.ConnectProviderOperation;
-import org.eclipse.egit.core.op.DisconnectProviderOperation;
-import org.eclipse.egit.core.test.GitTestCase;
-import org.eclipse.egit.core.test.TestProject;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.op.ConnectProviderOperation;
+import org.eclipse.egit.core.internal.op.DisconnectProviderOperation;
+import org.eclipse.egit.core.internal.test.GitTestCase;
+import org.eclipse.egit.core.internal.test.TestProject;
 import org.eclipse.jgit.api.Git;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.ObjectId;
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/storage/IndexFileRevisionTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/storage/IndexFileRevisionTest.java
index 5764616..6c1c06a 100644
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/storage/IndexFileRevisionTest.java
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/storage/IndexFileRevisionTest.java
@@ -15,7 +15,7 @@
 import java.nio.ByteBuffer;
 
 import org.eclipse.core.resources.IStorage;
-import org.eclipse.egit.core.test.GitTestCase;
+import org.eclipse.egit.core.internal.test.GitTestCase;
 import org.eclipse.jgit.dircache.DirCache;
 import org.eclipse.jgit.dircache.DirCacheBuilder;
 import org.eclipse.jgit.dircache.DirCacheEntry;
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/synchronize/AbstractCacheTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/synchronize/AbstractCacheTest.java
new file mode 100644
index 0000000..1d3566f
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/synchronize/AbstractCacheTest.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (C) 2011, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.synchronize;
+
+import static org.eclipse.egit.core.internal.synchronize.GitCommitsModelCache.ADDITION;
+import static org.eclipse.egit.core.internal.synchronize.GitCommitsModelCache.CHANGE;
+import static org.eclipse.egit.core.internal.synchronize.GitCommitsModelCache.DELETION;
+import static org.eclipse.egit.core.internal.synchronize.GitCommitsModelCache.RIGHT;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Map;
+
+import org.eclipse.egit.core.internal.synchronize.GitCommitsModelCache.Change;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase;
+import org.eclipse.jgit.lib.AbbreviatedObjectId;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.internal.storage.file.FileRepository;
+import org.junit.Before;
+
+@SuppressWarnings("boxing")
+public abstract class AbstractCacheTest extends LocalDiskRepositoryTestCase {
+
+	protected FileRepository db;
+
+	protected static final String INITIAL_TAG = "initial-tag";
+
+	protected static final AbbreviatedObjectId ZERO_ID = AbbreviatedObjectId.fromObjectId(ObjectId.zeroId());
+
+	@Before
+	@Override
+	// copied from org.eclipse.jgit.lib.RepositoryTestCase
+	public void setUp() throws Exception {
+		super.setUp();
+		db = createWorkRepository();
+		Git git = new Git(db);
+		git.commit().setMessage("initial commit").call();
+		git.tag().setName(INITIAL_TAG).call();
+	}
+
+	protected void assertFileAddition(Map<String, Change> result, String path, String fileName) {
+		commonFileAsserts(result, path, fileName);
+		assertThat(result.get(path).getKind(), is(RIGHT | ADDITION));
+		assertThat(result.get(path).getObjectId(), not(ZERO_ID));
+		assertNull(result.get(path).getRemoteObjectId());
+	}
+
+	protected void assertFileDeletion(Map<String, Change> result, String path, String fileName) {
+		commonFileAsserts(result, path, fileName);
+		assertThat(result.get(path).getKind(), is(RIGHT | DELETION));
+		assertThat(result.get(path).getRemoteObjectId(), not(ZERO_ID));
+		assertNull(result.get(path).getObjectId());
+	}
+
+	protected void assertFileChange(Map<String, Change> result, String path, String fileName) {
+		commonFileAsserts(result, path, fileName);
+		assertThat(result.get(path).getKind(), is(RIGHT | CHANGE));
+		assertThat(result.get(path).getObjectId(), not(ZERO_ID));
+		assertThat(result.get(path).getRemoteObjectId(), not(ZERO_ID));
+	}
+
+	private void commonFileAsserts(Map<String, Change> result, String path,
+			String fileName) {
+		assertTrue(result.containsKey(path));
+		assertThat(result.get(path).getName(), is(fileName));
+	}
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/synchronize/ChangeTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/synchronize/ChangeTest.java
new file mode 100644
index 0000000..1b4468d
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/synchronize/ChangeTest.java
@@ -0,0 +1,137 @@
+/*******************************************************************************
+ * Copyright (C) 2011, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.synchronize;
+
+import static org.eclipse.egit.core.internal.synchronize.GitCommitsModelCache.ZERO_ID;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.eclipse.egit.core.internal.synchronize.GitCommitsModelCache.Change;
+import org.eclipse.jgit.lib.AbbreviatedObjectId;
+import org.junit.Test;
+
+public class ChangeTest {
+
+	private static final AbbreviatedObjectId MISC_ID = AbbreviatedObjectId
+			.fromString("63448b851ae8831a1ad007f588508d3246ec7ace");
+
+	@Test
+	public void shouldNotBeEqualWithNullRefference() {
+		// given
+		Change change = new Change();
+
+		// when
+		boolean result = change.equals(null);
+
+		// then
+		assertFalse(result);
+	}
+
+	@Test
+	public void shouldNotBeEqualWithDifferentType() {
+		// given
+		Change change = new Change();
+
+		// when
+		boolean result = change.equals(new Object());
+
+		// then
+		assertFalse(result);
+	}
+
+	@Test
+	public void shouldBeEqualWhenBothIdsAreNull() {
+		// given
+		Change change = new Change();
+
+		// when
+		boolean result = change.equals(new Change());
+
+		// then
+		assertTrue(result);
+	}
+
+	@Test
+	public void shouldNotBeEqualWhenOneObjectIdIsNull() {
+		// given
+		Change change = new Change();
+		change.objectId = ZERO_ID;
+
+		// when
+		boolean result = change.equals(new Change());
+
+		// then
+		assertFalse(result);
+	}
+
+	@Test
+	public void shouldBeEqualWhenBothObjectIdsAreTheSame() {
+		// given
+		Change c1 = new Change();
+		Change c2 = new Change();
+		c1.objectId = c2.objectId = MISC_ID;
+
+		// when
+		boolean result = c1.equals(c2);
+
+		// then
+		assertTrue(result);
+		assertEquals(c1.hashCode(), c2.hashCode());
+	}
+
+	@Test
+	public void shouldNotBeEqualWhenObjectIdsAreDifferent() {
+		// given
+		Change c1 = new Change();
+		Change c2 = new Change();
+		c1.objectId = ZERO_ID;
+		c2.objectId = MISC_ID;
+
+		// when
+		boolean result = c1.equals(c2);
+
+		// then
+		assertFalse(result);
+		assertFalse(c1.hashCode() == c2.hashCode());
+	}
+
+	@Test
+	public void shouldNotBeEqualWhenOneRemoteObjectIsNull() {
+		// given
+		Change c1 = new Change();
+		Change c2 = new Change();
+		c1.objectId = c2.commitId = ZERO_ID;
+		c1.remoteObjectId = MISC_ID;
+
+		// when
+		boolean result = c1.equals(c2);
+
+		// then
+		assertFalse(result);
+		assertFalse(c1.hashCode() == c2.hashCode());
+	}
+
+	@Test
+	public void shouldBeEqualWhenBothObjectIdsAndRemoteIdsAreSame() {
+		// given
+		Change c1 = new Change();
+		Change c2 = new Change();
+		c1.objectId = c2.objectId = ZERO_ID;
+		c1.remoteObjectId = c2.remoteObjectId = MISC_ID;
+
+		// when
+		boolean result = c1.equals(c2);
+
+		// then
+		assertTrue(result);
+		assertEquals(c1.hashCode(), c2.hashCode());
+	}
+
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/synchronize/GitCommitsModelCacheTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/synchronize/GitCommitsModelCacheTest.java
new file mode 100644
index 0000000..b431838
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/synchronize/GitCommitsModelCacheTest.java
@@ -0,0 +1,578 @@
+/*******************************************************************************
+ * Copyright (C) 2011, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.synchronize;
+
+import static org.eclipse.egit.core.internal.synchronize.GitCommitsModelCache.ADDITION;
+import static org.eclipse.egit.core.internal.synchronize.GitCommitsModelCache.CHANGE;
+import static org.eclipse.egit.core.internal.synchronize.GitCommitsModelCache.DELETION;
+import static org.eclipse.egit.core.internal.synchronize.GitCommitsModelCache.LEFT;
+import static org.eclipse.egit.core.internal.synchronize.GitCommitsModelCache.RIGHT;
+import static org.eclipse.jgit.junit.JGitTestUtil.deleteTrashFile;
+import static org.eclipse.jgit.junit.JGitTestUtil.writeTrashFile;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.Matchers.nullValue;
+import static org.junit.Assert.assertThat;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.eclipse.egit.core.internal.synchronize.GitCommitsModelCache;
+import org.eclipse.egit.core.internal.synchronize.GitCommitsModelCache.Change;
+import org.eclipse.egit.core.internal.synchronize.GitCommitsModelCache.Commit;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.errors.AmbiguousObjectException;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.treewalk.filter.PathFilter;
+import org.junit.Test;
+
+@SuppressWarnings("boxing")
+public class GitCommitsModelCacheTest extends AbstractCacheTest {
+	@Test
+	public void shouldReturnEmptyListForSameSrcAndDstCommit() throws Exception {
+		// given
+		Git git = new Git(db);
+		RevCommit c = commit(git, "second commit");
+		// when
+		List<Commit> result = GitCommitsModelCache.build(db, c, c, null);
+		// then
+		assertThat(result, notNullValue());
+		assertThat(result.size(), is(0));
+	}
+
+	@Test
+	public void shouldNotListEmptyCommits() throws Exception {
+		// given
+		Git git = new Git(db);
+		RevCommit c = commit(git, "second commit");
+		// when
+		List<Commit> result = GitCommitsModelCache.build(db, initialTagId(), c,
+				null);
+		// then
+		assertThat(result, notNullValue());
+		assertThat(result.size(), is(0));
+	}
+
+	@Test
+	public void shouldListAdditionOrDeletionInCommit() throws Exception {
+		// given
+		Git git = new Git(db);
+		writeTrashFile(db, "a.txt", "content");
+		git.add().addFilepattern("a.txt").call();
+		RevCommit c = commit(git, "first commit");
+		// when
+		List<Commit> leftResult = GitCommitsModelCache.build(db,
+				initialTagId(), c, null);
+		List<Commit> rightResult = GitCommitsModelCache.build(db, c,
+				initialTagId(), null);
+		// then
+		// left assertions
+		assertThat(leftResult, notNullValue());
+		assertCommit(leftResult.get(0), c, 1);
+		assertFileDeletion(c, leftResult.get(0).getChildren().get("a.txt"),
+				"a.txt", LEFT);
+		// right asserts, after changing sides addition becomes deletion
+		assertThat(rightResult, notNullValue());
+		assertCommit(rightResult.get(0), c, 1);
+		assertFileAddition(c, rightResult.get(0).getChildren().get("a.txt"),
+				"a.txt", RIGHT);
+	}
+
+	@Test
+	public void shouldListAdditionOrDeletionInsideFolderInCommit()
+			throws Exception {
+		// given
+		Git git = new Git(db);
+		writeTrashFile(db, "folder/a.txt", "content");
+		git.add().addFilepattern("folder/a.txt").call();
+		RevCommit c = commit(git, "first commit");
+		// when
+		List<Commit> leftResult = GitCommitsModelCache.build(db,
+				initialTagId(), c, null);
+		List<Commit> rightResult = GitCommitsModelCache.build(db, c,
+				initialTagId(), null);
+		// then
+		// left assertions
+		assertThat(leftResult, notNullValue());
+		assertCommit(leftResult.get(0), c, 1);
+		assertThat(leftResult.get(0).getChildren().size(), is(1));
+		assertFileDeletion(c,
+				leftResult.get(0).getChildren().get("folder/a.txt"), "a.txt",
+				LEFT);
+		// right asserts, after changing sides addition becomes deletion
+		assertThat(rightResult, notNullValue());
+		assertCommit(rightResult.get(0), c, 1);
+		assertThat(rightResult.get(0).getChildren().size(), is(1));
+		assertFileAddition(c,
+				rightResult.get(0).getChildren().get("folder/a.txt"), "a.txt",
+				RIGHT);
+	}
+
+	@Test
+	public void shouldListAdditionsOrDeletionsInsideSeparateFoldersInCommit()
+			throws Exception {
+		// given
+		Git git = new Git(db);
+		writeTrashFile(db, "folder/a.txt", "content");
+		writeTrashFile(db, "folder2/b.txt", "b content");
+		git.add().addFilepattern("folder/a.txt").call();
+		git.add().addFilepattern("folder2/b.txt").call();
+		RevCommit c = commit(git, "first commit");
+		// when
+		List<Commit> leftResult = GitCommitsModelCache.build(db,
+				initialTagId(), c, null);
+		List<Commit> rightResult = GitCommitsModelCache.build(db, c,
+				initialTagId(), null);
+		// then
+		// left assertions
+		assertThat(leftResult, notNullValue());
+		assertThat(Integer.valueOf(leftResult.size()), is(Integer.valueOf(1)));
+		assertThat(leftResult.get(0).getShortMessage(), is("first commit"));
+		assertThat(leftResult.get(0).getChildren(), notNullValue());
+		assertThat(leftResult.get(0).getChildren().size(), is(2));
+		assertFileDeletion(c,
+				leftResult.get(0).getChildren().get("folder/a.txt"), "a.txt",
+				LEFT);
+		assertFileDeletion(c,
+				leftResult.get(0).getChildren().get("folder2/b.txt"), "b.txt",
+				LEFT);
+		// right asserts, after changing sides addition becomes deletion
+		assertThat(rightResult, notNullValue());
+		assertThat(Integer.valueOf(rightResult.size()), is(Integer.valueOf(1)));
+		assertThat(rightResult.get(0).getShortMessage(), is("first commit"));
+		assertThat(rightResult.get(0).getChildren(), notNullValue());
+		assertThat(rightResult.get(0).getChildren().size(), is(2));
+		assertFileAddition(c,
+				rightResult.get(0).getChildren().get("folder/a.txt"), "a.txt",
+				RIGHT);
+		assertFileAddition(c,
+				rightResult.get(0).getChildren().get("folder2/b.txt"), "b.txt",
+				RIGHT);
+	}
+
+	@Test
+	public void shouldApplyPathFilter() throws Exception {
+		// given
+		Git git = new Git(db);
+		writeTrashFile(db, "folder/a.txt", "content");
+		writeTrashFile(db, "folder2/b.txt", "b content");
+		git.add().addFilepattern("folder/a.txt").call();
+		git.add().addFilepattern("folder2/b.txt").call();
+		RevCommit c = commit(git, "first commit");
+
+		// when
+		PathFilter pathFilter = PathFilter.create("folder");
+		List<Commit> leftResult = GitCommitsModelCache.build(db,
+				initialTagId(), c, pathFilter);
+		// then
+		assertThat(leftResult, notNullValue());
+		assertThat(Integer.valueOf(leftResult.size()), is(Integer.valueOf(1)));
+		assertThat(leftResult.get(0).getShortMessage(), is("first commit"));
+		assertThat(leftResult.get(0).getChildren(), notNullValue());
+		assertThat(leftResult.get(0).getChildren().size(), is(1));
+		assertFileDeletion(c,
+				leftResult.get(0).getChildren().get("folder/a.txt"), "a.txt",
+				LEFT);
+	}
+
+	@Test
+	public void shouldListAdditionsOrDeletionsInsideFolderInCommit()
+			throws Exception {
+		// given
+		Git git = new Git(db);
+		writeTrashFile(db, "folder/a.txt", "content");
+		writeTrashFile(db, "folder/b.txt", "b content");
+		git.add().addFilepattern("folder").call();
+		RevCommit c = commit(git, "first commit");
+		// when
+		List<Commit> leftResult = GitCommitsModelCache.build(db,
+				initialTagId(), c, null);
+		List<Commit> rightResult = GitCommitsModelCache.build(db, c,
+				initialTagId(), null);
+		// then
+		// left assertions
+		assertThat(leftResult, notNullValue());
+		assertThat(Integer.valueOf(leftResult.size()), is(Integer.valueOf(1)));
+		assertCommit(leftResult.get(0), c, 2);
+		assertThat(leftResult.get(0).getChildren().size(), is(2));
+		assertFileDeletion(c,
+				leftResult.get(0).getChildren().get("folder/a.txt"), "a.txt",
+				LEFT);
+		assertFileDeletion(c,
+				leftResult.get(0).getChildren().get("folder/b.txt"), "b.txt",
+				LEFT);
+		// right asserts, after changing sides addition becomes deletion
+		assertThat(rightResult, notNullValue());
+		assertThat(Integer.valueOf(rightResult.size()), is(Integer.valueOf(1)));
+		assertCommit(rightResult.get(0), c, 2);
+		assertThat(rightResult.get(0).getChildren().size(), is(2));
+		assertFileAddition(c,
+				rightResult.get(0).getChildren().get("folder/a.txt"), "a.txt",
+				RIGHT);
+		assertFileAddition(c,
+				rightResult.get(0).getChildren().get("folder/b.txt"), "b.txt",
+				RIGHT);
+	}
+
+	@Test
+	public void shouldListChangeInCommit() throws Exception {
+		// given
+		Git git = new Git(db);
+		writeTrashFile(db, "a.txt", "content");
+		git.add().addFilepattern("a.txt").call();
+		RevCommit c1 = commit(git, "first commit");
+		writeTrashFile(db, "a.txt", "new content");
+		RevCommit c2 = commit(git, "second commit");
+		// when
+		List<Commit> leftResult = GitCommitsModelCache.build(db, c1, c2, null);
+		List<Commit> rightResult = GitCommitsModelCache.build(db, c2, c1, null);
+		// then
+		// left assertions
+		assertThat(leftResult, notNullValue());
+		assertCommit(leftResult.get(0), c2, 1);
+		assertFileChange(c1, c2, leftResult.get(0).getChildren().get("a.txt"),
+				"a.txt", LEFT);
+		// right asserts
+		assertThat(rightResult, notNullValue());
+		assertCommit(rightResult.get(0), c2, 1);
+		assertFileChange(c2, c1, rightResult.get(0).getChildren().get("a.txt"),
+				"a.txt", RIGHT);
+	}
+
+	@Test
+	public void shouldListChangeInsideFolderInCommit() throws Exception {
+		// given
+		Git git = new Git(db);
+		writeTrashFile(db, "folder/a.txt", "content");
+		git.add().addFilepattern("folder/a.txt").call();
+		RevCommit c1 = commit(git, "first commit");
+		writeTrashFile(db, "folder/a.txt", "new content");
+		RevCommit c2 = commit(git, "second commit");
+		// when
+		List<Commit> leftResult = GitCommitsModelCache.build(db, c1, c2, null);
+		List<Commit> rightResult = GitCommitsModelCache.build(db, c2, c1, null);
+		// then
+		// left assertions
+		assertThat(leftResult, notNullValue());
+		assertCommit(leftResult.get(0), c2, 1);
+		assertFileChange(c1, c2,
+				leftResult.get(0).getChildren().get("folder/a.txt"), "a.txt",
+				LEFT);
+		// right asserts
+		assertThat(rightResult, notNullValue());
+		assertCommit(rightResult.get(0), c2, 1);
+		assertFileChange(c2, c1,
+				rightResult.get(0).getChildren().get("folder/a.txt"), "a.txt",
+				RIGHT);
+	}
+
+	@Test
+	public void shouldListChangesInsideSeparateFoldersInCommit()
+			throws Exception {
+		// given
+		Git git = new Git(db);
+		writeTrashFile(db, "folder/a.txt", "content");
+		writeTrashFile(db, "folder2/b.txt", "b content");
+		git.add().addFilepattern("folder/a.txt").call();
+		git.add().addFilepattern("folder2/b.txt").call();
+		RevCommit c1 = commit(git, "first commit");
+		writeTrashFile(db, "folder/a.txt", "new content");
+		writeTrashFile(db, "folder2/b.txt", "new b content");
+		RevCommit c2 = commit(git, "second commit");
+		// when
+		List<Commit> leftResult = GitCommitsModelCache.build(db, c1, c2, null);
+		List<Commit> rightResult = GitCommitsModelCache.build(db, c2, c1, null);
+		// then
+		// left assertions
+		assertThat(leftResult, notNullValue());
+		assertThat(Integer.valueOf(leftResult.size()), is(Integer.valueOf(1)));
+		assertThat(leftResult.get(0).getShortMessage(), is("second commit"));
+		assertThat(leftResult.get(0).getChildren(), notNullValue());
+		assertThat(leftResult.get(0).getChildren().size(), is(2));
+		assertFileChange(c1, c2,
+				leftResult.get(0).getChildren().get("folder/a.txt"), "a.txt",
+				LEFT);
+		assertFileChange(c1, c2,
+				leftResult.get(0).getChildren().get("folder2/b.txt"), "b.txt",
+				LEFT);
+		// right asserts
+		assertThat(rightResult, notNullValue());
+		assertThat(Integer.valueOf(rightResult.size()), is(Integer.valueOf(1)));
+		assertThat(rightResult.get(0).getShortMessage(), is("second commit"));
+		assertThat(rightResult.get(0).getChildren().size(), is(2));
+		assertFileChange(c2, c1,
+				rightResult.get(0).getChildren().get("folder/a.txt"), "a.txt",
+				RIGHT);
+		assertFileChange(c2, c1,
+				rightResult.get(0).getChildren().get("folder2/b.txt"), "b.txt",
+				RIGHT);
+	}
+
+	@Test
+	public void shouldListChangesInsideFolderInCommit() throws Exception {
+		// given
+		Git git = new Git(db);
+		writeTrashFile(db, "folder/a.txt", "content");
+		writeTrashFile(db, "folder/b.txt", "b content");
+		git.add().addFilepattern("folder").call();
+		RevCommit c1 = commit(git, "first commit");
+		writeTrashFile(db, "folder/a.txt", "new content");
+		writeTrashFile(db, "folder/b.txt", "new b content");
+		RevCommit c2 = commit(git, "second commit");
+		// when
+		List<Commit> leftResult = GitCommitsModelCache.build(db, c1, c2, null);
+		List<Commit> rightResult = GitCommitsModelCache.build(db, c2, c1, null);
+		// then
+		// left assertions
+		assertThat(leftResult, notNullValue());
+		assertThat(Integer.valueOf(leftResult.size()), is(Integer.valueOf(1)));
+		assertCommit(leftResult.get(0), c2, 2);
+		assertFileChange(c1, c2,
+				leftResult.get(0).getChildren().get("folder/a.txt"), "a.txt",
+				LEFT);
+		assertFileChange(c1, c2,
+				leftResult.get(0).getChildren().get("folder/b.txt"), "b.txt",
+				LEFT);
+		// right asserts
+		assertThat(rightResult, notNullValue());
+		assertThat(Integer.valueOf(rightResult.size()), is(Integer.valueOf(1)));
+		assertCommit(rightResult.get(0), c2, 2);
+		assertFileChange(c2, c1,
+				rightResult.get(0).getChildren().get("folder/a.txt"), "a.txt",
+				RIGHT);
+		assertFileChange(c2, c1,
+				rightResult.get(0).getChildren().get("folder/b.txt"), "b.txt",
+				RIGHT);
+	}
+
+	@Test
+	public void shouldListAllTypeOfChangesInOneCommit() throws Exception {
+		// given
+		Git git = new Git(db);
+		writeTrashFile(db, "a.txt", "a content");
+		writeTrashFile(db, "c.txt", "c content");
+		git.add().addFilepattern("a.txt").call();
+		git.add().addFilepattern("c.txt").call();
+		RevCommit c1 = commit(git, "first commit");
+		deleteTrashFile(db, "a.txt");
+		writeTrashFile(db, "b.txt", "b content");
+		writeTrashFile(db, "c.txt", "new c content");
+		git.add().addFilepattern("b.txt").call();
+		RevCommit c2 = commit(git, "second commit");
+		// when
+		List<Commit> leftResult = GitCommitsModelCache.build(db, c1, c2, null);
+		List<Commit> rightResult = GitCommitsModelCache.build(db, c2, c1, null);
+		// then
+		// left asserts
+		assertThat(leftResult, notNullValue());
+		assertCommit(leftResult.get(0), c2, 3);
+		assertFileAddition(c1, c2,
+				leftResult.get(0).getChildren().get("a.txt"), "a.txt", LEFT);
+		assertFileDeletion(c1, c2,
+				leftResult.get(0).getChildren().get("b.txt"), "b.txt", LEFT);
+		assertFileChange(c1, c2, leftResult.get(0).getChildren().get("c.txt"),
+				"c.txt", LEFT);
+		// right asserts
+		assertThat(rightResult, notNullValue());
+		assertCommit(rightResult.get(0), c2, 3);
+		assertFileDeletion(c2, c1, rightResult.get(0).getChildren()
+				.get("a.txt"), "a.txt", RIGHT);
+		assertFileAddition(c2, c1, rightResult.get(0).getChildren()
+				.get("b.txt"), "b.txt", RIGHT);
+		assertFileChange(c2, c1, rightResult.get(0).getChildren().get("c.txt"),
+				"c.txt", RIGHT);
+	}
+
+	@Test
+	public void shouldListAllTypeOfChangesInsideFolderInOneCommit()
+			throws Exception {
+		// given
+		Git git = new Git(db);
+		writeTrashFile(db, "folder/a.txt", "a content");
+		writeTrashFile(db, "folder/c.txt", "c content");
+		git.add().addFilepattern("folder/a.txt").call();
+		git.add().addFilepattern("folder/c.txt").call();
+		RevCommit c1 = commit(git, "first commit");
+		deleteTrashFile(db, "folder/a.txt");
+		writeTrashFile(db, "folder/b.txt", "b content");
+		writeTrashFile(db, "folder/c.txt", "new c content");
+		git.add().addFilepattern("folder/b.txt").call();
+		RevCommit c2 = commit(git, "second commit");
+		// when
+		List<Commit> leftResult = GitCommitsModelCache.build(db, c1, c2, null);
+		List<Commit> rightResult = GitCommitsModelCache.build(db, c2, c1, null);
+		// then
+		// left assertions
+		assertThat(leftResult, notNullValue());
+		assertCommit(leftResult.get(0), c2, 3);
+		assertFileAddition(c1, c2,
+				leftResult.get(0).getChildren().get("folder/a.txt"), "a.txt",
+				LEFT);
+		assertFileDeletion(c1, c2,
+				leftResult.get(0).getChildren().get("folder/b.txt"), "b.txt",
+				LEFT);
+		assertFileChange(c1, c2,
+				leftResult.get(0).getChildren().get("folder/c.txt"), "c.txt",
+				LEFT);
+		// right asserts
+		assertThat(rightResult, notNullValue());
+		assertCommit(rightResult.get(0), c2, 3);
+		assertFileDeletion(c2, c1,
+				rightResult.get(0).getChildren().get("folder/a.txt"), "a.txt",
+				RIGHT);
+		assertFileAddition(c2, c1,
+				rightResult.get(0).getChildren().get("folder/b.txt"), "b.txt",
+				RIGHT);
+		assertFileChange(c2, c1,
+				rightResult.get(0).getChildren().get("folder/c.txt"), "c.txt",
+				RIGHT);
+	}
+
+	@Test
+	public void shouldListAllTypeOfChangesInsideSeparateFoldersInOneCommit()
+			throws Exception {
+		// given
+		Git git = new Git(db);
+		writeTrashFile(db, "folder/a.txt", "a content");
+		writeTrashFile(db, "folder2/c.txt", "c content");
+		git.add().addFilepattern("folder/a.txt").call();
+		git.add().addFilepattern("folder2/c.txt").call();
+		RevCommit c1 = commit(git, "first commit");
+		deleteTrashFile(db, "folder/a.txt");
+		writeTrashFile(db, "folder1/b.txt", "b content");
+		writeTrashFile(db, "folder2/c.txt", "new c content");
+		git.add().addFilepattern("folder1/b.txt").call();
+		RevCommit c2 = commit(git, "second commit");
+		// when
+		List<Commit> leftResult = GitCommitsModelCache.build(db, c1, c2, null);
+		List<Commit> rightResult = GitCommitsModelCache.build(db, c2, c1, null);
+		// then
+		// left assertions
+		assertThat(leftResult, notNullValue());
+		assertThat(Integer.valueOf(leftResult.size()), is(Integer.valueOf(1)));
+		assertThat(leftResult.get(0).getShortMessage(), is("second commit"));
+		assertThat(leftResult.get(0).getChildren(), notNullValue());
+		assertThat(leftResult.get(0).getChildren().size(), is(3));
+		assertFileAddition(c1, c2,
+				leftResult.get(0).getChildren().get("folder/a.txt"), "a.txt",
+				LEFT);
+		assertFileDeletion(c1, c2,
+				leftResult.get(0).getChildren().get("folder1/b.txt"), "b.txt",
+				LEFT);
+		assertFileChange(c1, c2,
+				leftResult.get(0).getChildren().get("folder2/c.txt"), "c.txt",
+				LEFT);
+		// right asserts
+		assertThat(rightResult, notNullValue());
+		assertThat(Integer.valueOf(rightResult.size()), is(Integer.valueOf(1)));
+		assertThat(rightResult.get(0).getShortMessage(), is("second commit"));
+		assertThat(rightResult.get(0).getChildren(), notNullValue());
+		assertThat(rightResult.get(0).getChildren().size(), is(3));
+		assertFileDeletion(c2, c1,
+				rightResult.get(0).getChildren().get("folder/a.txt"), "a.txt",
+				RIGHT);
+		assertFileAddition(c2, c1,
+				rightResult.get(0).getChildren().get("folder1/b.txt"), "b.txt",
+				RIGHT);
+		assertFileChange(c2, c1,
+				rightResult.get(0).getChildren().get("folder2/c.txt"), "c.txt",
+				RIGHT);
+	}
+
+	private RevCommit commit(Git git, String msg) throws Exception {
+		tick();
+		return git.commit().setAll(true).setMessage(msg)
+				.setCommitter(committer).call();
+	}
+
+	private ObjectId initialTagId() throws AmbiguousObjectException,
+			IOException {
+		return db.resolve(INITIAL_TAG);
+	}
+
+	private void assertCommit(Commit commit, RevCommit actualCommit,
+			int childrenCount) {
+		commonCommitAsserts(commit, actualCommit);
+		assertThat(commit.getChildren(), notNullValue());
+		assertThat(commit.getChildren().size(), is(childrenCount));
+	}
+
+	private void commonCommitAsserts(Commit commit, RevCommit actualCommit) {
+		assertThat(commit.getShortMessage(), is(actualCommit.getShortMessage()));
+		assertThat(commit.getId().toObjectId(), is(actualCommit.getId()));
+		assertThat(commit.getAuthorName(), is(actualCommit.getAuthorIdent()
+				.getName()));
+		assertThat(commit.getCommitterName(), is(actualCommit
+				.getCommitterIdent().getName()));
+		assertThat(commit.getCommitDate(), is(actualCommit.getAuthorIdent()
+				.getWhen()));
+	}
+
+	private void assertFileChange(RevCommit actual, RevCommit parent,
+			Change change, String name, int direction) {
+		commonFileAssertions(actual, parent, change, name);
+		assertThat(change.getObjectId(), not(ZERO_ID));
+		assertThat(change.getRemoteObjectId(), not(ZERO_ID));
+		if (direction == LEFT)
+			assertThat(change.getKind(), is(LEFT | CHANGE));
+		else
+			assertThat(change.getKind(), is(RIGHT | CHANGE));
+	}
+
+	private void assertFileAddition(RevCommit actual, Change change,
+			String name, int direction) {
+		assertFileAddition(actual, null, change, name, direction);
+	}
+
+	private void assertFileAddition(RevCommit actual, RevCommit parent,
+			Change change, String name, int direction) {
+		commonFileAssertions(actual, parent, change, name);
+		if (direction == LEFT) {
+			assertThat(change.getKind(), is(LEFT | ADDITION));
+			assertThat(change.getRemoteCommitId(), not(ZERO_ID));
+			assertThat(change.getObjectId(), nullValue());
+		} else { // should be Differencer.Right
+			assertThat(change.getKind(), is(RIGHT | ADDITION));
+			assertThat(change.getObjectId(), not(ZERO_ID));
+			assertThat(change.getRemoteObjectId(), nullValue());
+		}
+	}
+
+	private void assertFileDeletion(RevCommit parent, Change change,
+			String name, int direction) {
+		assertFileDeletion(null, parent, change, name, direction);
+	}
+
+	private void assertFileDeletion(RevCommit actual, RevCommit parent,
+			Change change, String name, int direction) {
+		commonFileAssertions(actual, parent, change, name);
+		if (direction == LEFT) {
+			assertThat(change.getRemoteObjectId(), nullValue());
+			assertThat(change.getObjectId(), not(ZERO_ID));
+			assertThat(change.getKind(), is(LEFT | DELETION));
+		} else { // should be Differencer.Right
+			assertThat(change.getKind(), is(RIGHT | DELETION));
+			assertThat(change.getObjectId(), nullValue());
+			assertThat(change.getRemoteObjectId(), not(ZERO_ID));
+		}
+	}
+
+	private void commonFileAssertions(RevCommit actual, RevCommit parent,
+			Change change, String name) {
+		assertThat(change, notNullValue());
+		if (parent != null)
+			assertThat(change.getRemoteCommitId().toObjectId(),
+					is(parent.getId()));
+		if (actual != null && !ObjectId.zeroId().equals(actual))
+			assertThat(change.getCommitId().toObjectId(), is(actual.getId()));
+		assertThat(change.getName(), is(name));
+	}
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/synchronize/GitResourceVariantComparatorTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/synchronize/GitResourceVariantComparatorTest.java
new file mode 100644
index 0000000..7cbf053
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/synchronize/GitResourceVariantComparatorTest.java
@@ -0,0 +1,697 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.synchronize;
+
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+import static org.eclipse.jgit.lib.Constants.HEAD;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.util.Arrays;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.egit.core.internal.synchronize.GitRemoteFile;
+import org.eclipse.egit.core.internal.synchronize.GitRemoteFolder;
+import org.eclipse.egit.core.internal.synchronize.GitResourceVariantComparator;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeData;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeDataSet;
+import org.eclipse.egit.core.internal.test.GitTestCase;
+import org.eclipse.egit.core.internal.test.TestRepository;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.treewalk.TreeWalk;
+import org.eclipse.team.core.variants.IResourceVariant;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class GitResourceVariantComparatorTest extends GitTestCase {
+
+	private Repository repo;
+
+	private IProject iProject;
+
+	private TestRepository testRepo;
+
+	@Before
+	public void setUp() throws Exception {
+		super.setUp();
+
+		iProject = project.project;
+		testRepo = new TestRepository(gitDir);
+		testRepo.connect(iProject);
+		repo = RepositoryMapping.getMapping(iProject).getRepository();
+
+		// make initial commit
+		new Git(repo).commit().setAuthor("JUnit", "junit@jgit.org")
+				.setMessage("Initall commit").call();
+	}
+
+	@After
+	public void clearGitResources() throws Exception {
+		testRepo.disconnect(iProject);
+		testRepo.dispose();
+		repo = null;
+		super.tearDown();
+	}
+
+	/* ============================================
+	 * compare(IResource, IResourceVariant) tests
+	 * ============================================ */
+
+	/**
+	 * When remote variant wasn't found, compare method is called with null as
+	 * second parameter. In this case compare should return false.
+	 */
+	@Test
+	@SuppressWarnings("boxing")
+	public void shouldReturnFalseWhenRemoteDoesNotExist() {
+		// when
+		GitResourceVariantComparator grvc = new GitResourceVariantComparator(
+				null);
+
+		// given
+		IResource local = mock(IResource.class);
+		when(local.exists()).thenReturn(false);
+
+		// then
+		assertFalse(grvc.compare(local, null));
+	}
+
+	@Test
+	@SuppressWarnings("boxing")
+	public void shouldReturnFalseWhenRemoteDoesNotExist2() throws Exception {
+		// when
+		GitResourceVariantComparator grvc = new GitResourceVariantComparator(
+				null);
+
+		// given
+		IResource local = mock(IResource.class);
+		when(local.exists()).thenReturn(false);
+		IResourceVariant remote = new GitRemoteFolder(repo, null, null, null, "./");
+
+		// then
+		assertFalse(grvc.compare(local, remote));
+	}
+
+	/**
+	 * It is possible to have a local file that has same name as a remote
+	 * folder. In some cases that two resources can be compared. In this case
+	 * compare method should return false, because they aren't same resources
+	 */
+	@Test
+	@SuppressWarnings("boxing")
+	public void shouldReturnFalseWhenComparingFileAndContainer() {
+		// when
+		GitResourceVariantComparator grvc = new GitResourceVariantComparator(
+				null);
+
+		// given
+		IFile local = mock(IFile.class);
+		when(local.exists()).thenReturn(true);
+
+		IResourceVariant remote = mock(IResourceVariant.class);
+		when(remote.isContainer()).thenReturn(true);
+
+		// then
+		assertFalse(grvc.compare(local, remote));
+	}
+
+	/**
+	 * Comparing two folders that have different path should return false.
+	 *
+	 * @throws Exception
+	 */
+	@Test
+	@SuppressWarnings("boxing")
+	public void shouldReturnFalseWhenComparingContainerAndContainer()
+			throws Exception {
+		// when
+		GitResourceVariantComparator grvc = new GitResourceVariantComparator(
+				null);
+
+		// given
+		IPath localPath = mock(IPath.class);
+		IContainer local = mock(IContainer.class);
+		when(local.exists()).thenReturn(true);
+		when(local.getLocation()).thenReturn(localPath);
+
+		File file = testRepo.createFile(iProject, "test" + File.separator
+				+ "keep");
+		RevCommit commit = testRepo.addAndCommit(iProject, file,
+				"initial commit");
+		String path = Repository.stripWorkDir(repo.getWorkTree(), file);
+
+		GitRemoteFolder remote = new GitRemoteFolder(repo, null, commit,
+				commit.getTree(), path);
+
+		// then
+		assertFalse(grvc.compare(local, remote));
+	}
+
+	/**
+	 * When comparing two folders that have same path, compare() method should
+	 * return true.
+	 *
+	 * @throws Exception
+	 */
+	@Test
+	@SuppressWarnings("boxing")
+	public void shouldReturnTrueWhenComparingContainerAndContainer()
+			throws Exception {
+		// when
+		GitResourceVariantComparator grvc = new GitResourceVariantComparator(
+				null);
+
+		// given
+		File file = testRepo.createFile(iProject, "test" + File.separator
+				+ "keep");
+		RevCommit commit = testRepo.addAndCommit(iProject, file,
+				"initial commit");
+		String path = Repository.stripWorkDir(repo.getWorkTree(), file);
+		IPath iPath = new Path(path);
+
+		IContainer local = mock(IContainer.class);
+		when(local.exists()).thenReturn(true);
+		when(local.getLocation()).thenReturn(iPath);
+
+		GitRemoteFolder remote = new GitRemoteFolder(repo, null, commit,
+				commit.getTree(), path);
+
+		// then
+		assertTrue(grvc.compare(local, remote));
+	}
+
+	/**
+	 * Compare() should return false when comparing two files with different
+	 * content length
+	 *
+	 * @throws Exception
+	 */
+	@Test
+	@SuppressWarnings("boxing")
+	public void shouldReturnFalseWhenContentLengthIsDifferent()
+			throws Exception {
+		// when
+		byte[] shortContent = "short content".getBytes();
+		byte[] longContent = "very long long content".getBytes();
+		GitSynchronizeData data = new GitSynchronizeData(repo, HEAD, HEAD, true);
+		GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data);
+		GitResourceVariantComparator grvc = new GitResourceVariantComparator(
+				dataSet);
+
+		// given
+		IFile local = mock(IFile.class);
+		when(local.exists()).thenReturn(true);
+		when(local.getProject()).thenReturn(project.getProject());
+		when(local.getContents()).thenReturn(
+				new ByteArrayInputStream(longContent));
+
+		IStorage storage = mock(IStorage.class);
+		when(storage.getContents()).thenReturn(
+				new ByteArrayInputStream(shortContent));
+
+		IResourceVariant remote = mock(IResourceVariant.class);
+		when(remote.isContainer()).thenReturn(false);
+		when(remote.getStorage(any(IProgressMonitor.class))).thenReturn(
+				storage);
+
+		// then
+		assertFalse(grvc.compare(local, remote));
+	}
+
+	/**
+	 * Comparing two files that have same content length but having small
+	 * difference inside content should return false.
+	 *
+	 * @throws Exception
+	 */
+	@Test
+	@SuppressWarnings("boxing")
+	public void shouldReturnFalseWhenShortContentIsDifferent() throws Exception {
+		// when
+		byte[] localContent = "very long long content".getBytes();
+		// this typo should be here
+		byte[] remoteContent = "very long lonk content".getBytes();
+		GitSynchronizeData data = new GitSynchronizeData(repo, HEAD, HEAD, true);
+		GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data);
+		GitResourceVariantComparator grvc = new GitResourceVariantComparator(
+				dataSet);
+
+		// given
+		IFile local = mock(IFile.class);
+		when(local.exists()).thenReturn(true);
+		when(local.getProject()).thenReturn(project.getProject());
+		when(local.getContents()).thenReturn(
+				new ByteArrayInputStream(localContent));
+
+		IStorage storage = mock(IStorage.class);
+		when(storage.getContents()).thenReturn(
+				new ByteArrayInputStream(remoteContent));
+
+		IResourceVariant remote = mock(IResourceVariant.class);
+		when(remote.isContainer()).thenReturn(false);
+		when(remote.getStorage(any(IProgressMonitor.class))).thenReturn(
+				storage);
+
+		// then
+		assertFalse(grvc.compare(local, remote));
+	}
+
+	/**
+	 * Comparing two 'large' files that have same length and almost identical
+	 * content should return false.
+	 *
+	 * @throws Exception
+	 */
+	@Test
+	@SuppressWarnings("boxing")
+	public void shouldReturnFalseWhenLongContentIsDifferent() throws Exception {
+		// when
+		byte[] localContent = new byte[8192];
+		Arrays.fill(localContent, (byte) 'a');
+		byte[] remoteContent = new byte[8192];
+		Arrays.fill(remoteContent, (byte) 'a');
+		remoteContent[8101] = 'b';
+		GitSynchronizeData data = new GitSynchronizeData(repo, HEAD, HEAD, true);
+		GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data);
+		GitResourceVariantComparator grvc = new GitResourceVariantComparator(
+				dataSet);
+
+		// given
+		IFile local = mock(IFile.class);
+		when(local.exists()).thenReturn(true);
+		when(local.getProject()).thenReturn(project.getProject());
+		when(local.getContents()).thenReturn(
+				new ByteArrayInputStream(localContent));
+
+		IStorage storage = mock(IStorage.class);
+		when(storage.getContents()).thenReturn(
+				new ByteArrayInputStream(remoteContent));
+
+		IResourceVariant remote = mock(IResourceVariant.class);
+		when(remote.isContainer()).thenReturn(false);
+		when(remote.getStorage(any(IProgressMonitor.class))).thenReturn(
+				storage);
+
+		// then
+		assertFalse(grvc.compare(local, remote));
+	}
+
+	/**
+	 * Comparing two 'large' files that have different length but same content
+	 * should return false.
+	 * <p>
+	 * This and previous three test cases cover almost the same functionality
+	 * but they are covering all return points in compare methods that can be
+	 * used when comparing files content
+	 *
+	 * @throws Exception
+	 */
+	@Test
+	@SuppressWarnings("boxing")
+	public void shouldReturnFalseWhenLongContentLengthIsDifferent()
+			throws Exception {
+		// when
+		byte[] localContent = new byte[8192];
+		Arrays.fill(localContent, (byte) 'a');
+		byte[] remoteContent = new byte[8200];
+		Arrays.fill(remoteContent, (byte) 'a');
+		GitSynchronizeData data = new GitSynchronizeData(repo, HEAD, HEAD, true);
+		GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data);
+		GitResourceVariantComparator grvc = new GitResourceVariantComparator(
+				dataSet);
+
+		// given
+		IFile local = mock(IFile.class);
+		when(local.exists()).thenReturn(true);
+		when(local.getProject()).thenReturn(project.getProject());
+		when(local.getContents()).thenReturn(
+				new ByteArrayInputStream(localContent));
+
+		IStorage storage = mock(IStorage.class);
+		when(storage.getContents()).thenReturn(
+				new ByteArrayInputStream(remoteContent));
+
+		IResourceVariant remote = mock(IResourceVariant.class);
+		when(remote.isContainer()).thenReturn(false);
+		when(remote.getStorage(any(IProgressMonitor.class))).thenReturn(
+				storage);
+
+		// then
+		assertFalse(grvc.compare(local, remote));
+	}
+
+	/**
+	 * Comparing two files that have the same content and content length should
+	 * return true
+	 *
+	 * @throws Exception
+	 */
+	@Test
+	@SuppressWarnings("boxing")
+	public void shouldReturnTrueWhenShortContentIsDifferent() throws Exception {
+		// when
+		byte[] localContent = "very long long content".getBytes();
+		byte[] remoteContent = "very long long content".getBytes();
+		GitSynchronizeData data = new GitSynchronizeData(repo, HEAD, HEAD, true);
+		GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data);
+		GitResourceVariantComparator grvc = new GitResourceVariantComparator(
+				dataSet);
+
+		// given
+		IFile local = mock(IFile.class);
+		when(local.exists()).thenReturn(true);
+		when(local.getProject()).thenReturn(project.getProject());
+		when(local.getContents()).thenReturn(
+				new ByteArrayInputStream(localContent));
+
+		IStorage storage = mock(IStorage.class);
+		when(storage.getContents()).thenReturn(
+				new ByteArrayInputStream(remoteContent));
+
+		IResourceVariant remote = mock(IResourceVariant.class);
+		when(remote.isContainer()).thenReturn(false);
+		when(remote.getStorage(any(IProgressMonitor.class))).thenReturn(
+				storage);
+
+		// then
+		assertTrue(grvc.compare(local, remote));
+	}
+
+	/**
+	 * Compare two 'large' files that have same content length and content
+	 * should return true.
+	 *
+	 * @throws Exception
+	 */
+	@Test
+	@SuppressWarnings("boxing")
+	public void shouldReturnTrueWhenLongContentLengthIsDifferent()
+			throws Exception {
+		// when
+		byte[] localContent = new byte[8192];
+		Arrays.fill(localContent, (byte) 'a');
+		byte[] remoteContent = new byte[8192];
+		Arrays.fill(remoteContent, (byte) 'a');
+		GitSynchronizeData data = new GitSynchronizeData(repo, HEAD, HEAD, true);
+		GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data);
+		GitResourceVariantComparator grvc = new GitResourceVariantComparator(
+				dataSet);
+
+		// given
+		IFile local = mock(IFile.class);
+		when(local.exists()).thenReturn(true);
+		when(local.getProject()).thenReturn(project.getProject());
+		when(local.getContents()).thenReturn(
+				new ByteArrayInputStream(localContent));
+
+		IStorage storage = mock(IStorage.class);
+		when(storage.getContents()).thenReturn(
+				new ByteArrayInputStream(remoteContent));
+
+		IResourceVariant remote = mock(IResourceVariant.class);
+		when(remote.isContainer()).thenReturn(false);
+		when(remote.getStorage(any(IProgressMonitor.class))).thenReturn(
+				storage);
+
+		// then
+		assertTrue(grvc.compare(local, remote));
+	}
+
+	/* ==================================================
+	 * compare(IResourceVariant, IResourceVariant) tests
+	 * ================================================== */
+
+	/**
+	 * When comparing file that don't exist in base, but exists in remote
+	 * compare method should return false.
+	 *
+	 * @throws Exception
+	 */
+	@Test
+	public void shouldReturnFalseWhenBaseDoesntExist() throws Exception {
+		// when
+		GitResourceVariantComparator grvc = new GitResourceVariantComparator(
+				null);
+
+		// given
+		RevCommit baseCommit = testRepo.createInitialCommit("initial commit");
+		testRepo.createAndCheckoutBranch(Constants.HEAD, Constants.R_HEADS
+				+ "test");
+		File file = testRepo.createFile(iProject, "test-file");
+		RevCommit remoteCommit = testRepo.addAndCommit(iProject, file,
+				"second commit");
+		String path = Repository.stripWorkDir(repo.getWorkTree(), file);
+
+		GitRemoteFile base = new GitRemoteFile(repo, baseCommit,
+				baseCommit.getTree(), path);
+		GitRemoteFile remote = new GitRemoteFile(repo, baseCommit,
+				remoteCommit.getTree(), path);
+
+		// then
+		assertFalse(grvc.compare(base, remote));
+	}
+
+	/**
+	 * Compare() should return false when remote file does not exists, but
+	 * equivalent local file exist.
+	 *
+	 * @throws Exception
+	 */
+	@Test
+	public void shouldReturnFalseWhenRemoteVariantDoesntExist()
+			throws Exception {
+		// when
+		GitResourceVariantComparator grvc = new GitResourceVariantComparator(
+				null);
+
+		// given
+		RevCommit remoteCommit = testRepo.createInitialCommit("initial commit");
+		testRepo.createAndCheckoutBranch(Constants.HEAD, Constants.R_HEADS
+				+ "test");
+		File file = testRepo.createFile(iProject, "test-file");
+		RevCommit baseCommit = testRepo.addAndCommit(iProject, file,
+				"second commit");
+		String path = Repository.stripWorkDir(repo.getWorkTree(), file);
+
+		GitRemoteFile base = new GitRemoteFile(repo, baseCommit,
+				baseCommit.getTree(), path);
+		GitRemoteFile remote = new GitRemoteFile(repo, remoteCommit,
+				remoteCommit.getTree(), path);
+
+		// then
+		assertFalse(grvc.compare(base, remote));
+	}
+
+	/**
+	 * Return false when comparing incompatible types (file against folder) that
+	 * also maps onto different resources
+	 *
+	 * @throws Exception
+	 */
+	@Test
+	public void shouldReturnFalseWhenComparingRemoteVariantFileWithContainer()
+			throws Exception {
+		// when
+		GitResourceVariantComparator grvc = new GitResourceVariantComparator(
+				null);
+
+		// given
+		File file = testRepo.createFile(iProject, "test" + File.separator
+				+ "keep");
+		RevCommit commit = testRepo.addAndCommit(iProject, file,
+				"initial commit");
+		String filePath = Repository.stripWorkDir(repo.getWorkTree(), file);
+		String folderPath = Repository.stripWorkDir(repo.getWorkTree(),
+				new File(file.getParent()));
+		GitRemoteFile base = new GitRemoteFile(repo, commit, commit.getTree(),
+				filePath);
+		GitRemoteFolder remote = new GitRemoteFolder(repo, null, commit,
+				commit.getTree(), folderPath);
+
+		// then
+		assertFalse(grvc.compare(base, remote));
+	}
+
+	/**
+	 * Return false when comparing incompatible types (folder against file) that
+	 * also map onto different resources
+	 *
+	 * @throws Exception
+	 */
+	@Test
+	public void shouldReturnFalseWhenComparingRemoteVariantContainerWithFile()
+			throws Exception {
+		// when
+		GitResourceVariantComparator grvc = new GitResourceVariantComparator(
+				null);
+
+		// given
+		File file = testRepo.createFile(iProject, "test" + File.separator
+				+ "keep");
+		RevCommit commit = testRepo.addAndCommit(iProject, file,
+				"initial commit");
+		String filePath = Repository.stripWorkDir(repo.getWorkTree(), file);
+		String folderPath = Repository.stripWorkDir(repo.getWorkTree(),
+				new File(file.getParent()));
+
+		GitRemoteFolder base = new GitRemoteFolder(repo, null, commit,
+				commit.getTree(), folderPath);
+		GitRemoteFile remote = new GitRemoteFile(repo, commit,
+				commit.getTree(), filePath);
+
+		// then
+		assertFalse(grvc.compare(base, remote));
+	}
+
+	/**
+	 * When comparing two remote variants that have different path compare
+	 * method should return false
+	 *
+	 * @throws Exception
+	 */
+	@Test
+	public void shouldReturnFalseWhenComparingRemoteVariantContainerWithContainer()
+			throws Exception {
+		// when
+		GitResourceVariantComparator grvc = new GitResourceVariantComparator(
+				null);
+
+		// given
+		File file1 = testRepo.createFile(iProject, "test1" + File.separator
+				+ "keep1");
+		File file2 = testRepo.createFile(iProject, "test2" + File.separator
+				+ "keep2");
+		testRepo.track(file1);
+		testRepo.track(file2);
+		testRepo.addToIndex(testRepo.getIFile(iProject, file1));
+		testRepo.addToIndex(testRepo.getIFile(iProject, file2));
+		RevCommit commit = testRepo.commit("initial commit");
+
+		TreeWalk tw = new TreeWalk(repo);
+		int nth = tw.addTree(commit.getTree());
+
+		tw.next();
+		tw.enterSubtree(); // enter project node
+		tw.next();
+		GitRemoteFolder base = new GitRemoteFolder(repo, null, commit,
+				tw.getObjectId(nth), tw.getNameString());
+
+		tw.next();
+		GitRemoteFolder remote = new GitRemoteFolder(repo, null, commit,
+				tw.getObjectId(nth), tw.getNameString());
+
+		// then
+		assertFalse(grvc.compare(base, remote));
+	}
+
+	/**
+	 * Comparing two remote folders that have same path should return true
+	 *
+	 * @throws Exception
+	 */
+	@Test
+	public void shouldReturnTrueWhenComparingRemoteVariantContainerWithContainer()
+			throws Exception {
+		// when
+		GitResourceVariantComparator grvc = new GitResourceVariantComparator(
+				null);
+
+		// given
+		File file1 = testRepo.createFile(iProject, "test1" + File.separator
+				+ "keep1");
+		testRepo.track(file1);
+		testRepo.addToIndex(testRepo.getIFile(iProject, file1));
+		RevCommit commit = testRepo.commit("initial commit");
+
+		String path1 = Repository.stripWorkDir(repo.getWorkTree(), new File(
+				file1.getParent()));
+
+		GitRemoteFolder base = new GitRemoteFolder(repo, null, commit,
+				commit.getTree(), path1);
+		GitRemoteFolder remote = new GitRemoteFolder(repo, null, commit,
+				commit.getTree(), path1);
+
+		// then
+		assertTrue(grvc.compare(base, remote));
+	}
+
+	/**
+	 * Comparing two remote files that have different git ObjectId should return false.
+	 *
+	 * @throws Exception
+	 */
+	@Test
+	public void shouldReturnFalseWhenComparingRemoteVariantWithDifferentObjectId()
+			throws Exception {
+		// when
+		GitResourceVariantComparator grvc = new GitResourceVariantComparator(
+				null);
+
+		// given
+		File file = testRepo.createFile(iProject, "test-file");
+		RevCommit baseCommit = testRepo.appendContentAndCommit(iProject, file,
+				"a", "initial commit");
+		RevCommit remoteCommit = testRepo.appendContentAndCommit(iProject,
+				file, "bc", "second commit");
+
+		String path = Repository.stripWorkDir(repo.getWorkTree(), file);
+		GitRemoteFile base = new GitRemoteFile(repo, baseCommit,
+				baseCommit.getTree(), path);
+
+		GitRemoteFile remote = new GitRemoteFile(repo, remoteCommit,
+				remoteCommit.getTree(), path);
+
+		// then
+		assertFalse(grvc.compare(base, remote));
+	}
+
+	/**
+	 * Comparing two remote files that have the same git ObjectId should return
+	 * true.
+	 *
+	 * @throws Exception
+	 */
+	@Test
+	public void shouldReturnTrueWhenComparingRemoteVariant() throws Exception {
+		// when
+		GitResourceVariantComparator grvc = new GitResourceVariantComparator(
+				null);
+
+		// given
+		File file = testRepo.createFile(iProject, "test-file");
+		RevCommit commit = testRepo.appendContentAndCommit(iProject, file,
+				"a", "initial commit");
+
+		String path = Repository.stripWorkDir(repo.getWorkTree(), file);
+		GitRemoteFile base = new GitRemoteFile(repo, commit, commit.getTree(),
+				path);
+
+		GitRemoteFile remote = new GitRemoteFile(repo, commit,
+				commit.getTree(), path);
+
+		// then
+		assertTrue(grvc.compare(base, remote));
+	}
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/synchronize/GitResourceVariantTreeSubscriberTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/synchronize/GitResourceVariantTreeSubscriberTest.java
new file mode 100755
index 0000000..a6c9758
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/synchronize/GitResourceVariantTreeSubscriberTest.java
@@ -0,0 +1,219 @@
+/*******************************************************************************
+ * Copyright (C) 2010, 2012 Dariusz Luksza <dariusz@luksza.org> and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.synchronize;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.egit.core.internal.synchronize.GitBaseResourceVariantTree;
+import org.eclipse.egit.core.internal.synchronize.GitRemoteResource;
+import org.eclipse.egit.core.internal.synchronize.GitRemoteResourceVariantTree;
+import org.eclipse.egit.core.internal.synchronize.GitResourceVariantTreeSubscriber;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeData;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeDataSet;
+import org.eclipse.egit.core.internal.test.GitTestCase;
+import org.eclipse.egit.core.internal.test.TestRepository;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.treewalk.TreeWalk;
+import org.eclipse.jgit.treewalk.filter.PathFilter;
+import org.eclipse.team.core.TeamException;
+import org.eclipse.team.core.variants.IResourceVariant;
+import org.eclipse.team.core.variants.IResourceVariantTree;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class GitResourceVariantTreeSubscriberTest extends GitTestCase {
+
+	private Repository repo;
+
+	private IProject iProject;
+
+	private TestRepository testRepo;
+
+	@Before
+	public void setUp() throws Exception {
+		super.setUp();
+		iProject = project.getProject();
+		testRepo = new TestRepository(gitDir);
+		testRepo.connect(iProject);
+		repo = RepositoryMapping.getMapping(iProject).getRepository();
+	}
+
+	@After
+	public void clearGitResources() throws Exception {
+		testRepo.disconnect(iProject);
+		testRepo.dispose();
+		repo = null;
+		super.tearDown();
+	}
+
+	/**
+	 * This test simulates that user work and made some changes on branch 'test'
+	 * and then try to synchronize "test" and 'master' branch.
+	 *
+	 * @throws Exception
+	 */
+	@Test
+	public void shouldReturnSrcBranchAsBase() throws Exception {
+		// when
+		String fileName = "Main.java";
+		File file = testRepo.createFile(iProject, fileName);
+		RevCommit commit = testRepo.appendContentAndCommit(iProject, file,
+				"class Main {}", "initial commit");
+		IFile mainJava = testRepo.getIFile(iProject, file);
+		testRepo.createAndCheckoutBranch(Constants.HEAD, Constants.R_HEADS
+				+ "test");
+		testRepo.appendContentAndCommit(iProject, file, "// test1",
+				"secont commit");
+
+		// given
+		GitResourceVariantTreeSubscriber grvts = createGitResourceVariantTreeSubscriber(
+				Constants.HEAD, Constants.R_HEADS + Constants.MASTER);
+		grvts.init(new NullProgressMonitor());
+		IResourceVariantTree baseTree = grvts.getBaseTree();
+
+		// then
+		IResourceVariant actual = commonAssertionsForBaseTree(baseTree,
+				mainJava);
+		assertEquals(commit.abbreviate(7).name() + "... (J. Git)",
+				actual.getContentIdentifier());
+	}
+
+	/**
+	 * Both source and destination branches has some different commits but they
+	 * has also common ancestor. This situation is described more detailed in
+	 * bug #317934
+	 *
+	 * This test passes when it is run as a stand alone test case, but it fails
+	 * when it is run as part of test suite. It throws NPE when it try's to
+	 * checkout master branch.
+	 *
+	 * @throws Exception
+	 */
+	@Test
+	@Ignore
+	public void shouldReturnCommonAncestorAsBase() throws Exception {
+		// when
+		String fileName = "Main.java";
+		File file = testRepo.createFile(iProject, fileName);
+		RevCommit commit = testRepo.appendContentAndCommit(iProject, file,
+				"class Main {}", "initial commit");
+		IFile mainJava = testRepo.getIFile(iProject, file);
+		// this should be our common ancestor
+		ObjectId fileId = findFileId(commit, mainJava);
+
+		testRepo.createAndCheckoutBranch(Constants.HEAD, Constants.R_HEADS
+				+ "test");
+		testRepo.appendContentAndCommit(iProject, file, "// test 1",
+				"second commit");
+
+		testRepo.checkoutBranch(Constants.R_HEADS + Constants.MASTER);
+		testRepo.appendContentAndCommit(iProject, file, "// test 2",
+				"third commit");
+
+		// given
+		GitResourceVariantTreeSubscriber grvts = createGitResourceVariantTreeSubscriber(
+				Constants.HEAD, Constants.R_HEADS + "test");
+		grvts.getBaseTree();
+		IResourceVariantTree baseTree = grvts.getBaseTree();
+
+		// then
+		IResourceVariant actual = commonAssertionsForBaseTree(baseTree,
+				mainJava);
+		assertEquals(fileId.getName(), actual.getContentIdentifier());
+	}
+
+	/**
+	 * This test passes when it is run as a stand alone test case, but it fails
+	 * when it is run as part of test suite. It throws NPE when it try's to
+	 * checkout master branch.
+	 *
+	 * @throws Exception
+	 */
+	@Test
+	@Ignore
+	public void shouldReturnRemoteTree() throws Exception {
+		// when
+		String fileName = "Main.java";
+		File file = testRepo.createFile(iProject, fileName);
+		testRepo.appendContentAndCommit(iProject, file,
+				"class Main {}", "initial commit");
+		IFile mainJava = testRepo.getIFile(iProject, file);
+
+		testRepo.createAndCheckoutBranch(Constants.HEAD, Constants.R_HEADS
+				+ "test");
+		RevCommit commit = testRepo.appendContentAndCommit(iProject, file, "// test 1",
+				"second commit");
+		ObjectId fileId = findFileId(commit, mainJava);
+
+		// given
+		GitResourceVariantTreeSubscriber grvts = createGitResourceVariantTreeSubscriber(
+				Constants.HEAD, "test");
+		grvts.getBaseTree();
+		IResourceVariantTree remoteTree = grvts.getRemoteTree();
+
+		// then
+		assertNotNull(remoteTree);
+		assertTrue(remoteTree instanceof GitRemoteResourceVariantTree);
+		IResourceVariant resourceVariant = remoteTree
+				.getResourceVariant(mainJava);
+		assertNotNull(resourceVariant);
+		assertTrue(resourceVariant instanceof GitRemoteResource);
+		assertEquals(fileId.getName(), resourceVariant.getContentIdentifier());
+	}
+
+	private GitResourceVariantTreeSubscriber createGitResourceVariantTreeSubscriber(
+			String src, String dst) throws IOException {
+		GitSynchronizeData gsd = new GitSynchronizeData(repo, src, dst, false);
+		GitSynchronizeDataSet gsds = new GitSynchronizeDataSet(gsd);
+		new GitResourceVariantTreeSubscriber(gsds);
+		return new GitResourceVariantTreeSubscriber(gsds);
+	}
+
+	private ObjectId findFileId(RevCommit commit, IFile mainJava)
+			throws Exception {
+		TreeWalk tw = new TreeWalk(repo);
+		tw.reset();
+		tw.setRecursive(true);
+		String path = Repository.stripWorkDir(repo.getWorkTree(), mainJava
+				.getLocation().toFile());
+		tw.setFilter(PathFilter.create(path));
+		int nth = tw.addTree(commit.getTree());
+		tw.next();
+
+		return tw.getObjectId(nth);
+	}
+
+	private IResourceVariant commonAssertionsForBaseTree(
+			IResourceVariantTree baseTree, IResource resource)
+			throws TeamException {
+		assertNotNull(baseTree);
+		assertTrue(baseTree instanceof GitBaseResourceVariantTree);
+		IResourceVariant resourceVariant = baseTree
+				.getResourceVariant(resource);
+		assertNotNull(resourceVariant);
+		assertTrue(resourceVariant instanceof GitRemoteResource);
+		return resourceVariant;
+	}
+
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/synchronize/GitResourceVariantTreeTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/synchronize/GitResourceVariantTreeTest.java
new file mode 100644
index 0000000..453c18c
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/synchronize/GitResourceVariantTreeTest.java
@@ -0,0 +1,282 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.synchronize;
+
+import static org.eclipse.jgit.lib.Constants.HEAD;
+import static org.eclipse.jgit.lib.Constants.MASTER;
+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 java.io.File;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.Comparator;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.egit.core.internal.op.ConnectProviderOperation;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.egit.core.internal.synchronize.GitBaseResourceVariantTree;
+import org.eclipse.egit.core.internal.synchronize.GitRemoteResourceVariantTree;
+import org.eclipse.egit.core.internal.synchronize.GitResourceVariantTree;
+import org.eclipse.egit.core.internal.synchronize.GitSyncCache;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeData;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeDataSet;
+import org.eclipse.egit.core.internal.test.GitTestCase;
+import org.eclipse.egit.core.internal.test.TestProject;
+import org.eclipse.egit.core.internal.test.TestRepository;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.team.core.variants.IResourceVariant;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class GitResourceVariantTreeTest extends GitTestCase {
+
+	private Repository repo;
+
+	private IProject iProject;
+
+	private TestRepository testRepo;
+
+	@Before
+	public void createGitRepository() throws Exception {
+		iProject = project.project;
+		testRepo = new TestRepository(gitDir);
+		testRepo.connect(iProject);
+		repo = RepositoryMapping.getMapping(iProject).getRepository();
+	}
+
+	@After
+	public void clearGitResources() throws Exception {
+		testRepo.disconnect(iProject);
+		testRepo.dispose();
+		repo = null;
+		super.tearDown();
+	}
+
+	/**
+	 * roots() method should return list of projects that are associated with
+	 * given repository. In this case there is only one project associated with
+	 * this repository therefore only one root should be returned.
+	 *
+	 * @throws Exception
+	 */
+	@Test
+	public void shouldReturnOneRoot() throws Exception {
+		// when
+		new Git(repo).commit().setAuthor("JUnit", "junit@egit.org")
+				.setMessage("Initial commit").call();
+		GitSynchronizeData data = new GitSynchronizeData(repo, HEAD, HEAD,
+				false);
+		GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data);
+
+		// given
+		GitResourceVariantTree grvt = new GitTestResourceVariantTree(dataSet,
+				null, null);
+
+		// then
+		assertEquals(1, grvt.roots().length);
+		IResource actualProject = grvt.roots()[0];
+		assertEquals(this.project.getProject(), actualProject);
+	}
+
+	/**
+	 * When we have two or more project associated with repository, roots()
+	 * method should return list of project. In this case we have two project
+	 * associated with particular repository, therefore '2' value is expected.
+	 *
+	 * @throws Exception
+	 */
+	@Test
+	public void shouldReturnTwoRoots() throws Exception {
+		// when
+		// create second project
+		TestProject secondProject = new TestProject(true, "Project-2");
+		try {
+			IProject secondIProject = secondProject.project;
+			// add connect project with repository
+			new ConnectProviderOperation(secondIProject, gitDir).execute(null);
+			new Git(repo).commit().setAuthor("JUnit", "junit@egit.org")
+					.setMessage("Initial commit").call();
+			GitSynchronizeData data = new GitSynchronizeData(repo, HEAD, HEAD,
+					false);
+			GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data);
+
+			// given
+			GitResourceVariantTree grvt = new GitTestResourceVariantTree(dataSet,
+					null, null);
+
+			// then
+			IResource[] roots = grvt.roots();
+			// sort in order to be able to assert the project instances
+			Arrays.sort(roots, new Comparator<IResource>() {
+				public int compare(IResource r1, IResource r2) {
+					String path1 = r1.getFullPath().toString();
+					String path2 = r2.getFullPath().toString();
+					return path1.compareTo(path2);
+				}
+			});
+			assertEquals(2, roots.length);
+			IResource actualProject = roots[0];
+			assertEquals(this.project.project, actualProject);
+			IResource actualProject1 = roots[1];
+			assertEquals(secondIProject, actualProject1);
+		} finally {
+			secondProject.dispose();
+		}
+	}
+
+	/**
+	 * Checks that getResourceVariant will not throw NPE for null argument. This
+	 * method is called with null argument when local or remote resource does
+	 * not exist.
+	 *
+	 * @throws Exception
+	 */
+	@Test
+	public void shouldReturnNullResourceVariant() throws Exception {
+		// when
+		new Git(repo).commit().setAuthor("JUnit", "junit@egit.org")
+				.setMessage("Initial commit").call();
+		GitSynchronizeData data = new GitSynchronizeData(repo, HEAD, MASTER,
+				false);
+		GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data);
+
+		// given
+		GitResourceVariantTree grvt = new GitRemoteResourceVariantTree(null,
+				dataSet);
+
+		// then
+		assertNull(grvt.getResourceVariant(null));
+	}
+
+	/**
+	 * getResourceVariant() should return null when given resource doesn't exist
+	 * in repository.
+	 *
+	 * @throws Exception
+	 */
+	@Test
+	public void shouldReturnNullResourceVariant2() throws Exception {
+		// when
+		IPackageFragment iPackage = project.createPackage("org.egit.test");
+		IType mainJava = project.createType(iPackage, "Main.java",
+				"class Main {}");
+		new Git(repo).commit().setAuthor("JUnit", "junit@egit.org")
+				.setMessage("Initial commit").call();
+		GitSynchronizeData data = new GitSynchronizeData(repo, HEAD, MASTER,
+				false);
+		GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data);
+		GitSyncCache cache = GitSyncCache.getAllData(dataSet,
+				new NullProgressMonitor());
+
+		// given
+		GitResourceVariantTree grvt = new GitRemoteResourceVariantTree(cache,
+				dataSet);
+
+		// then
+		assertNull(grvt.getResourceVariant(mainJava.getResource()));
+	}
+
+	/**
+	 * Check if getResourceVariant() does return the same resource that was
+	 * committed. Passes only when it is run as a single test, not as a part of
+	 * largest test suite
+	 *
+	 * @throws Exception
+	 */
+	@Test
+	public void shoulReturnSameResourceVariant() throws Exception {
+		// when
+		String fileName = "Main.java";
+		File file = testRepo.createFile(iProject, fileName);
+		testRepo.appendContentAndCommit(iProject, file, "class Main {}",
+				"initial commit");
+		IFile mainJava = testRepo.getIFile(iProject, file);
+		GitSynchronizeData data = new GitSynchronizeData(repo, HEAD, MASTER,
+				false);
+		GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data);
+		GitSyncCache cache = GitSyncCache.getAllData(dataSet,
+				new NullProgressMonitor());
+
+		// given
+		GitResourceVariantTree grvt = new GitRemoteResourceVariantTree(cache,
+				dataSet);
+
+		// then
+		// null variant indicates that resource wasn't changed
+		assertNull(grvt.getResourceVariant(mainJava));
+	}
+
+	/**
+	 * Create and commit Main.java file in master branch, then create branch
+	 * "test" checkout nearly created branch and modify Main.java file.
+	 * getResourceVariant() should obtain Main.java file content from "master"
+	 * branch. Passes only when it is run as a single test, not as a part of
+	 * largest test suite
+	 *
+	 * @throws Exception
+	 */
+	@Test
+	public void shouldReturnDifferentResourceVariant() throws Exception {
+		// when
+		String fileName = "Main.java";
+		File file = testRepo.createFile(iProject, fileName);
+		testRepo.appendContentAndCommit(iProject, file, "class Main {}",
+				"initial commit");
+		IFile mainJava = testRepo.getIFile(iProject, file);
+
+		testRepo.createAndCheckoutBranch(Constants.R_HEADS + Constants.MASTER,
+				Constants.R_HEADS + "test");
+		testRepo.appendContentAndCommit(iProject, file, "// test",
+				"first commit");
+		GitSynchronizeData data = new GitSynchronizeData(repo, HEAD, MASTER,
+				true);
+		GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data);
+		GitSyncCache cache = GitSyncCache.getAllData(dataSet,
+				new NullProgressMonitor());
+
+		// given
+		GitResourceVariantTree grvt = new GitBaseResourceVariantTree(cache,
+				dataSet);
+
+		// then
+		IResourceVariant actual = grvt.getResourceVariant(mainJava);
+		assertNotNull(actual);
+		assertEquals(fileName, actual.getName());
+
+		InputStream actualIn = actual.getStorage(new NullProgressMonitor())
+				.getContents();
+		byte[] actualByte = getBytesAndCloseStream(actualIn);
+		InputStream expectedIn = mainJava.getContents();
+		byte[] expectedByte = getBytesAndCloseStream(expectedIn);
+
+		// assert arrays not equals
+		assertFalse(Arrays.equals(expectedByte, actualByte));
+	}
+
+	private byte[] getBytesAndCloseStream(InputStream stream) throws Exception {
+		try {
+			byte[] actualByte = new byte[stream.available()];
+			stream.read(actualByte);
+			return actualByte;
+		} finally {
+			stream.close();
+		}
+	}
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/synchronize/GitSubscriberMergeContextTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/synchronize/GitSubscriberMergeContextTest.java
new file mode 100644
index 0000000..f11d8e1
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/synchronize/GitSubscriberMergeContextTest.java
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * Copyright (C) 2011, 2012 Benjamin Muskalla <benjamin.muskalla@tasktop.com>
+ * and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.synchronize;
+
+import static junit.framework.Assert.assertTrue;
+import static org.eclipse.jgit.lib.Constants.HEAD;
+import static org.junit.Assert.assertEquals;
+
+import java.io.File;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.mapping.ResourceMapping;
+import org.eclipse.egit.core.internal.AdapterUtils;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.egit.core.internal.synchronize.GitResourceVariantTreeSubscriber;
+import org.eclipse.egit.core.internal.synchronize.GitSubscriberMergeContext;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeData;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeDataSet;
+import org.eclipse.egit.core.internal.test.GitTestCase;
+import org.eclipse.egit.core.internal.test.TestRepository;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.Status;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.team.core.diff.IDiff;
+import org.eclipse.team.core.mapping.provider.ResourceDiff;
+import org.eclipse.team.core.subscribers.SubscriberScopeManager;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class GitSubscriberMergeContextTest extends GitTestCase {
+
+	private Repository repo;
+
+	private IProject iProject;
+
+	private TestRepository testRepo;
+
+	@Before
+	public void setUp() throws Exception {
+		super.setUp();
+
+		iProject = project.project;
+		testRepo = new TestRepository(gitDir);
+		testRepo.connect(iProject);
+		repo = RepositoryMapping.getMapping(iProject).getRepository();
+
+		// make initial commit
+		new Git(repo).commit().setAuthor("JUnit", "junit@jgit.org")
+				.setMessage("Initial commit").call();
+	}
+
+	@After
+	public void clearGitResources() throws Exception {
+		testRepo.disconnect(iProject);
+		testRepo.dispose();
+		repo = null;
+		super.tearDown();
+	}
+
+	@Test
+	public void markAsMerged() throws Exception {
+		GitSynchronizeData gsd = new GitSynchronizeData(repo, HEAD, HEAD, false);
+		GitSynchronizeDataSet gsds = new GitSynchronizeDataSet(gsd);
+		GitResourceVariantTreeSubscriber subscriber = new GitResourceVariantTreeSubscriber(
+				gsds);
+
+		String fileName = "src/Main.java";
+		File file = testRepo.createFile(iProject, fileName);
+		testRepo.appendContentAndCommit(iProject, file, "class Main {}",
+				"some file");
+		testRepo.addToIndex(iProject.getFile(".classpath"));
+		testRepo.addToIndex(iProject.getFile(".project"));
+		testRepo.commit("project files");
+
+		IFile workspaceFile = testRepo.getIFile(iProject, file);
+
+		ResourceMapping mapping = AdapterUtils.adapt(workspaceFile, ResourceMapping.class);
+		ResourceMapping[] inputMappings = new ResourceMapping[] { mapping };
+		SubscriberScopeManager manager = new SubscriberScopeManager("Scope",
+				inputMappings, subscriber, true);
+
+		testRepo.appendFileContent(file, "some changes");
+		Status status = new Git(repo).status().call();
+		assertEquals(0, status.getAdded().size());
+		assertEquals(1, status.getModified().size());
+		String repoRelativePath = testRepo.getRepoRelativePath(workspaceFile.getLocation().toPortableString());
+		assertTrue(status.getModified().contains(repoRelativePath));
+
+		GitSubscriberMergeContext mergeContext = new GitSubscriberMergeContext(
+				subscriber, manager, gsds);
+		IDiff node = new ResourceDiff(iProject.getFolder("src"), IDiff.CHANGE);
+		mergeContext.markAsMerged(node, true, null);
+
+		status = new Git(repo).status().call();
+		assertEquals(1, status.getChanged().size());
+		assertEquals(0, status.getModified().size());
+		assertTrue(status.getChanged().contains(repoRelativePath));
+
+	}
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/synchronize/GitTestResourceVariantTree.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/synchronize/GitTestResourceVariantTree.java
new file mode 100644
index 0000000..11a24eb
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/synchronize/GitTestResourceVariantTree.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.synchronize;
+
+import org.eclipse.egit.core.internal.synchronize.GitResourceVariantTree;
+import org.eclipse.egit.core.internal.synchronize.GitSyncCache;
+import org.eclipse.egit.core.internal.synchronize.ThreeWayDiffEntry;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeData;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeDataSet;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.team.core.variants.ResourceVariantByteStore;
+
+/**
+ * Implementation of abstract {@link GitResourceVariantTree} class. It is only
+ * used in {@link GitResourceVariantTreeTest} for testing public methods that
+ * are implemented in base class.
+ */
+class GitTestResourceVariantTree extends GitResourceVariantTree {
+
+	GitTestResourceVariantTree(GitSynchronizeDataSet data,
+			GitSyncCache cache, ResourceVariantByteStore store) {
+		super(store, cache, data);
+	}
+
+	@Override
+	protected ObjectId getObjectId(ThreeWayDiffEntry diffEntry) {
+		return null;
+	}
+
+	@Override
+	protected RevCommit getCommitId(GitSynchronizeData gsd) {
+		return null;
+	}
+
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/synchronize/StagedChangeCacheTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/synchronize/StagedChangeCacheTest.java
new file mode 100644
index 0000000..069cd48
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/synchronize/StagedChangeCacheTest.java
@@ -0,0 +1,236 @@
+/*******************************************************************************
+ * Copyright (C) 2011, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.synchronize;
+
+import static org.eclipse.jgit.junit.JGitTestUtil.writeTrashFile;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import java.util.Map;
+
+import org.eclipse.egit.core.internal.synchronize.StagedChangeCache;
+import org.eclipse.egit.core.internal.synchronize.GitCommitsModelCache.Change;
+import org.eclipse.jgit.api.Git;
+import org.junit.Test;
+
+@SuppressWarnings("boxing")
+public class StagedChangeCacheTest extends AbstractCacheTest {
+
+	@Test
+	public void shouldListSingleWorkspaceAddition() throws Exception {
+		// given
+		writeTrashFile(db, "a.txt", "trash");
+		new Git(db).add().addFilepattern("a.txt").call();
+
+		// when
+		Map<String, Change> result = StagedChangeCache.build(db);
+
+		// then
+		assertThat(result.size(), is(1));
+		assertFileAddition(result, "a.txt", "a.txt");
+	}
+
+	@Test
+	public void shouldListTwoWorkspaceAdditions() throws Exception {
+		// given
+		writeTrashFile(db, "a.txt", "trash");
+		writeTrashFile(db, "b.txt", "trash");
+		new Git(db).add().addFilepattern("a.txt").addFilepattern("b.txt").call();
+
+		// when
+		Map<String, Change> result = StagedChangeCache.build(db);
+
+		// then
+		assertThat(result.size(), is(2));
+		assertFileAddition(result, "a.txt", "a.txt");
+		assertFileAddition(result, "b.txt", "b.txt");
+	}
+
+	@Test
+	public void shouldListSingleWorkspaceAdditionInFolder() throws Exception {
+		// given
+		writeTrashFile(db, "folder/a.txt", "trash");
+		new Git(db).add().addFilepattern("folder/a.txt").call();
+
+		// when
+		Map<String, Change> result = StagedChangeCache.build(db);
+
+		// then
+		assertThat(result.size(), is(1));
+		assertFileAddition(result, "folder/a.txt", "a.txt");
+	}
+
+	@Test
+	public void shouldListTwoWorkspaceAdditionsInFolder() throws Exception {
+		// given
+		writeTrashFile(db, "folder/a.txt", "trash");
+		writeTrashFile(db, "folder/b.txt", "trash");
+		new Git(db).add().addFilepattern("folder/a.txt").addFilepattern("folder/b.txt").call();
+
+		// when
+		Map<String, Change> result = StagedChangeCache.build(db);
+
+		// then
+		assertThat(result.size(), is(2));
+		assertFileAddition(result, "folder/a.txt", "a.txt");
+		assertFileAddition(result, "folder/b.txt", "b.txt");
+	}
+
+	@Test
+	public void shouldListSingleWorkspaceDeletion() throws Exception {
+		// given
+		Git git = new Git(db);
+		writeTrashFile(db, "a.txt", "trash");
+		git.add().addFilepattern("a.txt").call();
+		git.commit().setMessage("initial add").call();
+		git.rm().addFilepattern("a.txt").call();
+
+		// when
+		Map<String, Change> result = StagedChangeCache.build(db);
+
+		// then
+		assertThat(result.size(), is(1));
+		assertFileDeletion(result, "a.txt", "a.txt");
+	}
+
+	@Test
+	public void shouldListTwoWorkspaceDeletions() throws Exception {
+		// given
+		Git git = new Git(db);
+		writeTrashFile(db, "a.txt", "trash");
+		writeTrashFile(db, "b.txt", "trash");
+		git.add().addFilepattern("a.txt").addFilepattern("b.txt").call();
+		git.commit().setMessage("new commit").call();
+		git.rm().addFilepattern("a.txt").addFilepattern("b.txt").call();
+
+		// when
+		Map<String, Change> result = StagedChangeCache.build(db);
+
+		// then
+		assertThat(result.size(), is(2));
+		assertFileDeletion(result, "a.txt", "a.txt");
+		assertFileDeletion(result, "b.txt", "b.txt");
+	}
+
+	@Test
+	public void shouldListSingleWorkspaceDeletionInFolder() throws Exception {
+		// given
+		Git git = new Git(db);
+		writeTrashFile(db, "folder/a.txt", "trash");
+		git.add().addFilepattern("folder/a.txt").call();
+		git.commit().setMessage("new commit").call();
+		git.rm().addFilepattern("folder/a.txt").call();
+
+		// when
+		Map<String, Change> result = StagedChangeCache.build(db);
+
+		// then
+		assertThat(result.size(), is(1));
+		assertFileDeletion(result, "folder/a.txt", "a.txt");
+	}
+
+	@Test
+	public void shouldListTwoWorkspaceDeletionsInFolder() throws Exception {
+		// given
+		Git git = new Git(db);
+		writeTrashFile(db, "folder/a.txt", "trash");
+		writeTrashFile(db, "folder/b.txt", "trash");
+		git.add().addFilepattern("folder/a.txt").addFilepattern("folder/b.txt").call();
+		git.commit().setMessage("new commit").call();
+		git.rm().addFilepattern("folder/a.txt").call();
+		git.rm().addFilepattern("folder/b.txt").call();
+
+		// when
+		Map<String, Change> result = StagedChangeCache.build(db);
+
+		// then
+		assertThat(result.size(), is(2));
+		assertFileDeletion(result, "folder/a.txt", "a.txt");
+		assertFileDeletion(result, "folder/b.txt", "b.txt");
+	}
+
+	@Test
+	public void shouldListSingleWorkspaceChange() throws Exception {
+		// given
+		Git git = new Git(db);
+		writeTrashFile(db, "a.txt", "trash");
+		git.add().addFilepattern("a.txt").call();
+		git.commit().setMessage("initial a.txt commit").call();
+		writeTrashFile(db, "a.txt", "modification");
+		git.add().addFilepattern("a.txt").call();
+
+		// when
+		Map<String, Change> result = StagedChangeCache.build(db);
+
+		// then
+		assertThat(result.size(), is(1));
+		assertFileChange(result, "a.txt", "a.txt");
+	}
+
+	@Test
+	public void shouldListTwoWorkspaceChanges() throws Exception {
+		// given
+		Git git = new Git(db);
+		writeTrashFile(db, "a.txt", "trash");
+		writeTrashFile(db, "b.txt", "trash");
+		git.add().addFilepattern("a.txt").addFilepattern("b.txt").call();
+		git.commit().setMessage("new commmit").call();
+		writeTrashFile(db, "a.txt", "modification");
+		writeTrashFile(db, "b.txt", "modification");
+		git.add().addFilepattern("a.txt").addFilepattern("b.txt").call();
+
+		// when
+		Map<String, Change> result = StagedChangeCache.build(db);
+
+		// then
+		assertThat(result.size(), is(2));
+		assertFileChange(result, "a.txt", "a.txt");
+		assertFileChange(result, "b.txt", "b.txt");
+	}
+
+	@Test
+	public void shouldListSingleWorkspaceChangeInFolder() throws Exception {
+		// given
+		Git git = new Git(db);
+		writeTrashFile(db, "folder/a.txt", "trash");
+		git.add().addFilepattern("folder/a.txt").call();
+		git.commit().setMessage("new commit").call();
+		writeTrashFile(db, "folder/a.txt", "modification");
+		git.add().addFilepattern("folder/a.txt").call();
+
+		// when
+		Map<String, Change> result = StagedChangeCache.build(db);
+
+		// then
+		assertThat(result.size(), is(1));
+		assertFileChange(result, "folder/a.txt", "a.txt");
+	}
+
+	@Test
+	public void shouldListTwoWorkspaceChagneInFolder() throws Exception {
+		// given
+		Git git = new Git(db);
+		writeTrashFile(db, "folder/a.txt", "trash");
+		writeTrashFile(db, "folder/b.txt", "trash");
+		git.add().addFilepattern("folder/a.txt").addFilepattern("folder/b.txt").call();
+		git.commit().setMessage("new commit").call();
+		writeTrashFile(db, "folder/a.txt", "modification");
+		writeTrashFile(db, "folder/b.txt", "modification");
+		git.add().addFilepattern("folder/a.txt").addFilepattern("folder/b.txt").call();
+
+		// when
+		Map<String, Change> result = StagedChangeCache.build(db);
+
+		// then
+		assertThat(result.size(), is(2));
+		assertFileChange(result, "folder/a.txt", "a.txt");
+		assertFileChange(result, "folder/b.txt", "b.txt");
+	}
+
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/synchronize/ThreeWayDiffEntryTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/synchronize/ThreeWayDiffEntryTest.java
new file mode 100644
index 0000000..92623a1
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/synchronize/ThreeWayDiffEntryTest.java
@@ -0,0 +1,286 @@
+/*******************************************************************************
+ * Copyright (C) 2011, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.synchronize;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.junit.Assert.assertThat;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+import org.eclipse.egit.core.internal.synchronize.ThreeWayDiffEntry;
+import org.eclipse.egit.core.internal.synchronize.ThreeWayDiffEntry.ChangeType;
+import org.eclipse.egit.core.internal.synchronize.ThreeWayDiffEntry.Direction;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.internal.storage.file.FileRepository;
+import org.eclipse.jgit.treewalk.EmptyTreeIterator;
+import org.eclipse.jgit.treewalk.TreeWalk;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ThreeWayDiffEntryTest extends LocalDiskRepositoryTestCase {
+
+	private FileRepository db;
+
+	@Before
+	@Override
+	// copied from org.eclipse.jgit.lib.RepositoryTestCase
+	public void setUp() throws Exception {
+		super.setUp();
+		db = createWorkRepository();
+	}
+
+	@Test
+	public void shouldListOutgoingAddition() throws Exception {
+		// given
+		writeTrashFile("a.txt", "content");
+		Git git = new Git(db);
+		git.add().addFilepattern("a.txt").call();
+		RevCommit c = git.commit().setMessage("initial commit").call();
+
+		// when
+		TreeWalk walk = new TreeWalk(db);
+		walk.addTree(c.getTree());
+		walk.addTree(new EmptyTreeIterator());
+		walk.addTree(new EmptyTreeIterator());
+		List<ThreeWayDiffEntry> result = ThreeWayDiffEntry.scan(walk);
+
+		// then
+		assertThat(result, notNullValue());
+		assertThat(Integer.valueOf(result.size()), is(Integer.valueOf(1)));
+
+		ThreeWayDiffEntry entry = result.get(0);
+		assertThat(entry.getDirection(), is(Direction.OUTGOING));
+		assertThat(entry.getChangeType(), is(ChangeType.ADD));
+		assertThat(entry.getPath(), is("a.txt"));
+	}
+
+	@Test
+	public void shouldListIncomingAddition() throws Exception {
+		// given
+		writeTrashFile("a.txt", "content");
+		Git git = new Git(db);
+		git.add().addFilepattern("a.txt").call();
+		RevCommit c = git.commit().setMessage("initial commit").call();
+
+		// when
+		TreeWalk walk = new TreeWalk(db);
+		walk.addTree(new EmptyTreeIterator());
+		walk.addTree(new EmptyTreeIterator());
+		walk.addTree(c.getTree());
+		List<ThreeWayDiffEntry> result = ThreeWayDiffEntry.scan(walk);
+
+		// then
+		assertThat(result, notNullValue());
+		assertThat(Integer.valueOf(result.size()), is(Integer.valueOf(1)));
+
+		ThreeWayDiffEntry entry = result.get(0);
+		assertThat(entry.getDirection(), is(Direction.INCOMING));
+		assertThat(entry.getChangeType(), is(ChangeType.ADD));
+		assertThat(entry.getPath(), is("a.txt"));
+	}
+
+	@Test
+	public void shouldListOutgoingDelete() throws Exception {
+		// given
+		writeTrashFile("a.txt", "content");
+		Git git = new Git(db);
+		git.add().addFilepattern("a.txt").call();
+		RevCommit c = git.commit().setMessage("initial commit").call();
+
+		// when
+		TreeWalk walk = new TreeWalk(db);
+		walk.addTree(new EmptyTreeIterator());
+		walk.addTree(c.getTree());
+		walk.addTree(c.getTree());
+		List<ThreeWayDiffEntry> result = ThreeWayDiffEntry.scan(walk);
+
+		// then
+		assertThat(result, notNullValue());
+		assertThat(Integer.valueOf(result.size()), is(Integer.valueOf(1)));
+
+		ThreeWayDiffEntry entry = result.get(0);
+		assertThat(entry.getDirection(), is(Direction.OUTGOING));
+		assertThat(entry.getChangeType(), is(ChangeType.DELETE));
+		assertThat(entry.getPath(), is("a.txt"));
+	}
+
+	@Test
+	public void shouldListIncomingDelete() throws Exception {
+		// given
+		writeTrashFile("a.txt", "content");
+		Git git = new Git(db);
+		git.add().addFilepattern("a.txt").call();
+		RevCommit c = git.commit().setMessage("initial commit").call();
+
+		// when
+		TreeWalk walk = new TreeWalk(db);
+		walk.addTree(c.getTree());
+		walk.addTree(c.getTree());
+		walk.addTree(new EmptyTreeIterator());
+		List<ThreeWayDiffEntry> result = ThreeWayDiffEntry.scan(walk);
+
+		// then
+		assertThat(result, notNullValue());
+		assertThat(Integer.valueOf(result.size()), is(Integer.valueOf(1)));
+
+		ThreeWayDiffEntry entry = result.get(0);
+		assertThat(entry.getDirection(), is(Direction.INCOMING));
+		assertThat(entry.getChangeType(), is(ChangeType.DELETE));
+		assertThat(entry.getPath(), is("a.txt"));
+	}
+
+	@Test
+	public void shouldListConflictingChange() throws Exception {
+		// given
+		writeTrashFile("a.txt", "content");
+		Git git = new Git(db);
+		git.add().addFilepattern("a.txt").call();
+		RevCommit c = git.commit().setMessage("initial commit").call();
+
+		// when
+		TreeWalk walk = new TreeWalk(db);
+		walk.addTree(new EmptyTreeIterator());
+		walk.addTree(c.getTree());
+		walk.addTree(new EmptyTreeIterator());
+		List<ThreeWayDiffEntry> result = ThreeWayDiffEntry.scan(walk);
+
+		// then
+		assertThat(result, notNullValue());
+		assertThat(Integer.valueOf(result.size()), is(Integer.valueOf(1)));
+
+		ThreeWayDiffEntry entry = result.get(0);
+		assertThat(entry.getDirection(), is(Direction.CONFLICTING));
+		assertThat(entry.getChangeType(), is(ChangeType.MODIFY));
+		// assertThat(entry.getNewPath(), is("a.txt"));
+		// assertThat(entry.getOldPath(), is(DEV_NULL));
+	}
+
+	@Test
+	public void shouldListConflictingChange2() throws Exception {
+		// given
+		writeTrashFile("a.txt", "content");
+		Git git = new Git(db);
+		git.add().addFilepattern("a.txt").call();
+		RevCommit c = git.commit().setMessage("initial commit").call();
+
+		// when
+		TreeWalk walk = new TreeWalk(db);
+		walk.addTree(c.getTree());
+		walk.addTree(new EmptyTreeIterator());
+		walk.addTree(c.getTree());
+		List<ThreeWayDiffEntry> result = ThreeWayDiffEntry.scan(walk);
+
+		// then
+		assertThat(result, notNullValue());
+		assertThat(Integer.valueOf(result.size()), is(Integer.valueOf(1)));
+
+		ThreeWayDiffEntry entry = result.get(0);
+		assertThat(entry.getDirection(), is(Direction.CONFLICTING));
+		assertThat(entry.getChangeType(), is(ChangeType.MODIFY));
+		assertThat(entry.getPath(), is("a.txt"));
+	}
+
+	@Test
+	public void shouldListIncomingModify() throws Exception {
+		// given
+		writeTrashFile("a.txt", "content");
+		Git git = new Git(db);
+		git.add().addFilepattern("a.txt").call();
+		RevCommit c = git.commit().setMessage("initial commit").call();
+		writeTrashFile("a.txt", "new line");
+		RevCommit c1 = git.commit().setAll(true).setMessage("second commit")
+				.call();
+
+		// when
+		TreeWalk walk = new TreeWalk(db);
+		walk.addTree(c.getTree());
+		walk.addTree(c.getTree());
+		walk.addTree(c1.getTree());
+		List<ThreeWayDiffEntry> result = ThreeWayDiffEntry.scan(walk);
+
+		// then
+		assertThat(result, notNullValue());
+		assertThat(Integer.valueOf(result.size()), is(Integer.valueOf(1)));
+
+		ThreeWayDiffEntry entry = result.get(0);
+		assertThat(entry.getDirection(), is(Direction.INCOMING));
+		assertThat(entry.getChangeType(), is(ChangeType.MODIFY));
+		assertThat(entry.getPath(), is("a.txt"));
+	}
+
+	@Test
+	public void shouldListOutgoingModify() throws Exception {
+		// given
+		writeTrashFile("a.txt", "content");
+		Git git = new Git(db);
+		git.add().addFilepattern("a.txt").call();
+		RevCommit c = git.commit().setMessage("initial commit").call();
+		writeTrashFile("a.txt", "newe line");
+		RevCommit c1 = git.commit().setAll(true).setMessage("second commit")
+				.call();
+
+		// when
+		TreeWalk walk = new TreeWalk(db);
+		walk.addTree(c1.getTree());
+		walk.addTree(c.getTree());
+		walk.addTree(c.getTree());
+		List<ThreeWayDiffEntry> result = ThreeWayDiffEntry.scan(walk);
+
+		// then
+		assertThat(result, notNullValue());
+		assertThat(Integer.valueOf(result.size()), is(Integer.valueOf(1)));
+
+		ThreeWayDiffEntry entry = result.get(0);
+		assertThat(entry.getDirection(), is(Direction.OUTGOING));
+		assertThat(entry.getChangeType(), is(ChangeType.MODIFY));
+		assertThat(entry.getPath(), is("a.txt"));
+	}
+
+	@Test
+	public void shouldListConflictingModify() throws Exception {
+		// given
+		writeTrashFile("a.txt", "content");
+		Git git = new Git(db);
+		git.add().addFilepattern("a.txt").call();
+		RevCommit c = git.commit().setMessage("initial commit").call();
+		writeTrashFile("a.txt", "new line");
+		RevCommit c1 = git.commit().setAll(true).setMessage("second commit")
+				.call();
+
+		// when
+		TreeWalk walk = new TreeWalk(db);
+		walk.addTree(c1.getTree());
+		walk.addTree(c.getTree());
+		walk.addTree(c1.getTree());
+		List<ThreeWayDiffEntry> result = ThreeWayDiffEntry.scan(walk);
+
+		// then
+		assertThat(result, notNullValue());
+		assertThat(Integer.valueOf(result.size()), is(Integer.valueOf(1)));
+
+		ThreeWayDiffEntry entry = result.get(0);
+		assertThat(entry.getDirection(), is(Direction.CONFLICTING));
+		assertThat(entry.getChangeType(), is(ChangeType.MODIFY));
+		assertThat(entry.getPath(), is("a.txt"));
+	}
+
+	// copied from org.eclipse.jgit.lib.RepositoryTestCase
+	private File writeTrashFile(final String name, final String data)
+			throws IOException {
+		File path = new File(db.getWorkTree(), name);
+		write(path, data);
+		return path;
+	}
+
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/synchronize/WorkingTreeChangeCacheTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/synchronize/WorkingTreeChangeCacheTest.java
new file mode 100644
index 0000000..57ccb15
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/synchronize/WorkingTreeChangeCacheTest.java
@@ -0,0 +1,228 @@
+/*******************************************************************************
+ * Copyright (C) 2011, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.synchronize;
+
+import static org.eclipse.jgit.junit.JGitTestUtil.deleteTrashFile;
+import static org.eclipse.jgit.junit.JGitTestUtil.writeTrashFile;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import java.util.Map;
+
+import org.eclipse.egit.core.internal.synchronize.WorkingTreeChangeCache;
+import org.eclipse.egit.core.internal.synchronize.GitCommitsModelCache.Change;
+import org.eclipse.jgit.api.Git;
+import org.junit.Test;
+
+@SuppressWarnings("boxing")
+public class WorkingTreeChangeCacheTest extends AbstractCacheTest {
+
+	@Test
+	public void shouldListSingleWorkspaceAddition() throws Exception {
+		// given
+		writeTrashFile(db, "a.txt", "trash");
+
+		// when
+		Map<String, Change> result = WorkingTreeChangeCache.build(db);
+
+		// then
+		assertThat(result.size(), is(1));
+		assertFileAddition(result, "a.txt", "a.txt");
+	}
+
+	@Test
+	public void shouldListTwoWorkspaceAdditions() throws Exception {
+		// given
+		writeTrashFile(db, "a.txt", "trash");
+		writeTrashFile(db, "b.txt", "trash");
+
+		// when
+		Map<String, Change> result = WorkingTreeChangeCache.build(db);
+
+		// then
+		assertThat(result.size(), is(2));
+		assertFileAddition(result, "a.txt", "a.txt");
+		assertFileAddition(result, "b.txt", "b.txt");
+	}
+
+	@Test
+	public void shouldListSingleWorkspaceAdditionInFolder() throws Exception {
+		// given
+		writeTrashFile(db, "folder/a.txt", "trash");
+
+		// when
+		Map<String, Change> result = WorkingTreeChangeCache.build(db);
+
+		// then
+		assertThat(result.size(), is(1));
+		assertFileAddition(result, "folder/a.txt", "a.txt");
+	}
+
+	@Test
+	public void shouldListTwoWorkspaceAdditionsInFolder() throws Exception {
+		// given
+		writeTrashFile(db, "folder/a.txt", "trash");
+		writeTrashFile(db, "folder/b.txt", "trash");
+
+		// when
+		Map<String, Change> result = WorkingTreeChangeCache.build(db);
+
+		// then
+		assertThat(result.size(), is(2));
+		assertFileAddition(result, "folder/a.txt", "a.txt");
+		assertFileAddition(result, "folder/b.txt", "b.txt");
+	}
+
+	@Test
+	public void shouldListSingleWorkspaceDeletion() throws Exception {
+		// given
+		writeTrashFile(db, "a.txt", "trash");
+		new Git(db).add().addFilepattern("a.txt").call();
+		deleteTrashFile(db, "a.txt");
+
+		// when
+		Map<String, Change> result = WorkingTreeChangeCache.build(db);
+
+		// then
+		assertThat(result.size(), is(1));
+		assertFileDeletion(result, "a.txt", "a.txt");
+	}
+
+	@Test
+	public void shouldListTwoWorkspaceDeletions() throws Exception {
+		// given
+		writeTrashFile(db, "a.txt", "trash");
+		writeTrashFile(db, "b.txt", "trash");
+		new Git(db).add().addFilepattern("a.txt").addFilepattern("b.txt").call();
+		deleteTrashFile(db, "a.txt");
+		deleteTrashFile(db, "b.txt");
+
+		// when
+		Map<String, Change> result = WorkingTreeChangeCache.build(db);
+
+		// then
+		assertThat(result.size(), is(2));
+		assertFileDeletion(result, "a.txt", "a.txt");
+		assertFileDeletion(result, "b.txt", "b.txt");
+	}
+
+	@Test
+	public void shouldListSingleWorkspaceDeletionInFolder() throws Exception {
+		// given
+		writeTrashFile(db, "folder/a.txt", "trash");
+		new Git(db).add().addFilepattern("folder/a.txt").call();
+		deleteTrashFile(db, "folder/a.txt");
+
+		// when
+		Map<String, Change> result = WorkingTreeChangeCache.build(db);
+
+		// then
+		assertThat(result.size(), is(1));
+		assertFileDeletion(result, "folder/a.txt", "a.txt");
+	}
+
+	@Test
+	public void shouldListTwoWorkspaceDeletionsInFolder() throws Exception {
+		// given
+		writeTrashFile(db, "folder/a.txt", "trash");
+		writeTrashFile(db, "folder/b.txt", "trash");
+		new Git(db).add().addFilepattern("folder/a.txt").addFilepattern("folder/b.txt").call();
+		deleteTrashFile(db, "folder/a.txt");
+		deleteTrashFile(db, "folder/b.txt");
+
+		// when
+		Map<String, Change> result = WorkingTreeChangeCache.build(db);
+
+		// then
+		assertThat(result.size(), is(2));
+		assertFileDeletion(result, "folder/a.txt", "a.txt");
+		assertFileDeletion(result, "folder/b.txt", "b.txt");
+	}
+
+	@Test
+	public void shouldListSingleWorkspaceChange() throws Exception {
+		// given
+		writeTrashFile(db, "a.txt", "trash");
+		new Git(db).add().addFilepattern("a.txt").call();
+		writeTrashFile(db, "a.txt", "modification");
+
+		// when
+		Map<String, Change> result = WorkingTreeChangeCache.build(db);
+
+		// then
+		assertThat(result.size(), is(1));
+		assertFileChange(result, "a.txt", "a.txt");
+	}
+
+	@Test
+	public void shouldListTwoWorkspaceChanges() throws Exception {
+		// given
+		writeTrashFile(db, "a.txt", "trash");
+		writeTrashFile(db, "b.txt", "trash");
+		new Git(db).add().addFilepattern("a.txt").addFilepattern("b.txt").call();
+		writeTrashFile(db, "a.txt", "modification");
+		writeTrashFile(db, "b.txt", "modification");
+
+		// when
+		Map<String, Change> result = WorkingTreeChangeCache.build(db);
+
+		// then
+		assertThat(result.size(), is(2));
+		assertFileChange(result, "a.txt", "a.txt");
+		assertFileChange(result, "b.txt", "b.txt");
+	}
+
+	@Test
+	public void shouldListSingleWorkspaceChangeInFolder() throws Exception {
+		// given
+		writeTrashFile(db, "folder/a.txt", "trash");
+		new Git(db).add().addFilepattern("folder/a.txt").call();
+		writeTrashFile(db, "folder/a.txt", "modification");
+
+		// when
+		Map<String, Change> result = WorkingTreeChangeCache.build(db);
+
+		// then
+		assertThat(result.size(), is(1));
+		assertFileChange(result, "folder/a.txt", "a.txt");
+	}
+
+	@Test
+	public void shouldListTwoWorkspaceChagneInFolder() throws Exception {
+		// given
+		writeTrashFile(db, "folder/a.txt", "trash");
+		writeTrashFile(db, "folder/b.txt", "trash");
+		new Git(db).add().addFilepattern("folder/a.txt").addFilepattern("folder/b.txt").call();
+		writeTrashFile(db, "folder/a.txt", "modification");
+		writeTrashFile(db, "folder/b.txt", "modification");
+
+		// when
+		Map<String, Change> result = WorkingTreeChangeCache.build(db);
+
+		// then
+		assertThat(result.size(), is(2));
+		assertFileChange(result, "folder/a.txt", "a.txt");
+		assertFileChange(result, "folder/b.txt", "b.txt");
+	}
+
+	@Test
+	public void shouldNotListIgnorefFile() throws Exception {
+		// given
+		writeTrashFile(db, "a.txt", "content");
+		writeTrashFile(db, ".gitignore", "a.txt");
+
+		// when
+		Map<String, Change> result = WorkingTreeChangeCache.build(db);
+
+		// then
+		assertThat(result.size(), is(1));
+		assertFileAddition(result, ".gitignore", ".gitignore");
+	}
+
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/synchronize/dto/GitSynchronizeDataTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/synchronize/dto/GitSynchronizeDataTest.java
new file mode 100644
index 0000000..2f2fb50
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/synchronize/dto/GitSynchronizeDataTest.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (C) 2011, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.synchronize.dto;
+
+import static org.eclipse.jgit.lib.Constants.HEAD;
+import static org.eclipse.jgit.lib.Constants.R_HEADS;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeData;
+import org.eclipse.egit.core.internal.test.GitTestCase;
+import org.eclipse.egit.core.internal.test.TestRepository;
+import org.eclipse.jgit.api.CreateBranchCommand.SetupUpstreamMode;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.Repository;
+import org.junit.Before;
+import org.junit.Test;
+
+public class GitSynchronizeDataTest extends GitTestCase {
+
+	private Repository repo;
+
+	@Before
+	public void setUp() throws Exception {
+		super.setUp();
+
+		TestRepository testRepo = new TestRepository(gitDir);
+		testRepo.connect(project.project);
+		repo = RepositoryMapping.getMapping(project.project).getRepository();
+
+		// make initial commit
+		new Git(repo).commit().setAuthor("JUnit", "junit@jgit.org")
+				.setMessage("Initall commit").call();
+	}
+
+	@Test
+	public void shouldReturnSourceMergeForSymbolicRef() throws Exception {
+		// given
+		Git git = new Git(repo);
+		git.branchCreate().setName("test").setStartPoint("refs/heads/master")
+				.setUpstreamMode(SetupUpstreamMode.TRACK).call();
+		git.checkout().setName("test").call();
+		GitSynchronizeData gsd = new GitSynchronizeData(repo, HEAD, HEAD, false);
+
+		// when
+		String srcMerge = gsd.getSrcMerge();
+
+		// then
+		assertThat(srcMerge, is("refs/heads/master"));
+	}
+
+	@Test
+	public void shouldReturnSourceMergeForLocalRef() throws Exception {
+		// given
+		Git git = new Git(repo);
+		git.branchCreate().setName("test2").setStartPoint("refs/heads/master")
+				.setUpstreamMode(SetupUpstreamMode.TRACK).call();
+		git.checkout().setName("test2").call();
+		GitSynchronizeData gsd = new GitSynchronizeData(repo, R_HEADS + "test2",
+				HEAD, false);
+
+		// when
+		String srcMerge = gsd.getSrcMerge();
+
+		// then
+		assertThat(srcMerge, is("refs/heads/master"));
+	}
+
+	@Test
+	public void shouldReturnSourceMergeForRemoteBranch() throws Exception {
+		// given
+		Git git = new Git(repo);
+		git.branchCreate().setName("test3").setStartPoint("refs/heads/master")
+				.setUpstreamMode(SetupUpstreamMode.TRACK).call();
+		git.checkout().setName("test3").call();
+		repo.renameRef(R_HEADS + "test3", Constants.R_REMOTES + "origin/master").rename();
+		GitSynchronizeData gsd = new GitSynchronizeData(repo, "refs/remotes/origin/master",
+				HEAD, false);
+
+		// when
+		String srcMerge = gsd.getSrcMerge();
+
+		// then
+		assertThat(srcMerge, is("refs/heads/master"));
+	}
+
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/AdaptableFileTreeIteratorTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/AdaptableFileTreeIteratorTest.java
new file mode 100644
index 0000000..c35580f
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/AdaptableFileTreeIteratorTest.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (C) 2009, Tor Arne Vestbø <torarnv@gmail.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Set;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.egit.core.internal.AdaptableFileTreeIterator;
+import org.eclipse.egit.core.internal.ContainerTreeIterator;
+import org.eclipse.egit.core.internal.op.ConnectProviderOperation;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.internal.storage.file.FileRepository;
+import org.eclipse.jgit.treewalk.TreeWalk;
+import org.eclipse.jgit.treewalk.WorkingTreeIterator;
+import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
+import org.junit.Before;
+import org.junit.Test;
+
+public class AdaptableFileTreeIteratorTest extends GitTestCase {
+
+	private Repository repository;
+
+	private File file;
+
+	@Before
+	public void setUp() throws Exception {
+		super.setUp();
+
+		repository = new FileRepository(gitDir);
+		repository.create();
+
+		file = new File(project.getProject().getLocation().toFile(), "a.txt");
+		final FileWriter fileWriter = new FileWriter(file);
+		fileWriter.write("aaaaaaaaaaa");
+		fileWriter.close();
+
+		final ConnectProviderOperation operation = new ConnectProviderOperation(
+				project.getProject(), gitDir);
+		operation.execute(null);
+	}
+
+	@Test
+	public void testFileTreeToContainerAdaptation() throws IOException {
+		final IWorkspaceRoot root = project.getProject().getWorkspace()
+				.getRoot();
+
+		final TreeWalk treeWalk = new TreeWalk(repository);
+		treeWalk.addTree(new AdaptableFileTreeIterator(repository, root));
+		treeWalk.setRecursive(true);
+
+		final IFile eclipseFile = project.getProject().getFile(file.getName());
+		final RepositoryMapping mapping = RepositoryMapping
+				.getMapping(eclipseFile);
+		final Set<String> repositoryPaths = Collections.singleton(mapping
+				.getRepoRelativePath(eclipseFile));
+
+		assertEquals(1, repositoryPaths.size());
+		treeWalk.setFilter(PathFilterGroup.createFromStrings(repositoryPaths));
+
+		assertTrue(treeWalk.next());
+
+		final WorkingTreeIterator iterator = treeWalk.getTree(0,
+				WorkingTreeIterator.class);
+		assertTrue(iterator instanceof ContainerTreeIterator);
+	}
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/ContainerTreeIteratorResourceFilterTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/ContainerTreeIteratorResourceFilterTest.java
new file mode 100644
index 0000000..3e182d6
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/ContainerTreeIteratorResourceFilterTest.java
@@ -0,0 +1,244 @@
+/*******************************************************************************
+ * Copyright (C) 2012, Robin Stocker <robin@nibor.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.test;
+
+import static org.eclipse.core.resources.IResourceFilterDescription.EXCLUDE_ALL;
+import static org.eclipse.core.resources.IResourceFilterDescription.FILES;
+import static org.eclipse.core.resources.IResourceFilterDescription.FOLDERS;
+import static org.eclipse.core.resources.IResourceFilterDescription.INHERITABLE;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.hasItem;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.FileInfoMatcherDescription;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.egit.core.internal.AdaptableFileTreeIterator;
+import org.eclipse.egit.core.internal.ContainerTreeIterator;
+import org.eclipse.egit.core.internal.op.ConnectProviderOperation;
+import org.eclipse.jgit.internal.storage.file.FileRepository;
+import org.eclipse.jgit.treewalk.AbstractTreeIterator;
+import org.eclipse.jgit.treewalk.TreeWalk;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Test for how {@link ContainerTreeIterator} handles filtered resources.
+ * <p>
+ * The tricky thing is that they are not returned from API like
+ * {@link IContainer#members()}. So we have to fall back to using an
+ * {@link AdaptableFileTreeIterator} if there may be resource filters active.
+ * <p>
+ * In case of nested projects where the subproject is filtered in the parent
+ * project with resource filters, we want the nested project to be walked with
+ * {@link ContainerTreeIterator} again. That is, it should "recover" from
+ * falling back to {@link AdaptableFileTreeIterator}.
+ */
+public class ContainerTreeIteratorResourceFilterTest extends GitTestCase {
+
+	private FileRepository repository;
+
+	@Before
+	public void setUp() throws Exception {
+		super.setUp();
+
+		repository = new FileRepository(gitDir);
+		repository.create();
+
+		connectProject(project.getProject());
+	}
+
+	@Test
+	public void simpleNonInheritableFilter() throws Exception {
+		IProject p = project.getProject();
+		IFile filtered = testUtils.addFileToProject(p, "filtered.txt", "");
+		IFile unfiltered = testUtils.addFileToProject(p, "unfiltered.txt", "");
+		assertTrue("IFile should exist before filtering.", filtered.exists());
+		assertTrue("IFile should exist before filtering.", unfiltered.exists());
+
+		createFilter(p, EXCLUDE_ALL | FILES, "filtered.txt");
+		assertFalse("IFile should no longer exist after filtering.", filtered.exists());
+		assertTrue("IFile should exist after filtering.", unfiltered.exists());
+
+		List<Entry> entries = walkTree();
+
+		assertThat(entries, hasItem(containerTreeEntry("Project-1/filtered.txt")));
+		assertThat(entries, hasItem(containerTreeEntry("Project-1/unfiltered.txt")));
+	}
+
+	@Test
+	public void simpleNonInheritableFolderFilter() throws Exception {
+		IProject p = project.getProject();
+		IFile filtered = testUtils.addFileToProject(p, "folder/filtered.txt", "");
+		IFile unfiltered = testUtils.addFileToProject(p, "folder2/unfiltered.txt", "");
+
+		createFilter(p, EXCLUDE_ALL | FOLDERS, "folder");
+		assertFalse("IFile should no longer exist after filtering.", filtered.exists());
+		assertTrue("IFile should exist after filtering.", unfiltered.exists());
+
+		List<Entry> entries = walkTree();
+
+		assertThat(entries, hasItem(adaptableFileTreeEntry("Project-1/folder/filtered.txt")));
+		assertThat(entries, hasItem(containerTreeEntry("Project-1/folder2/unfiltered.txt")));
+	}
+
+	@Test
+	public void inheritableFilter() throws Exception {
+		IProject p = project.getProject();
+		IFile filtered1 = testUtils.addFileToProject(p, "folder1/filtered.txt", "");
+		IFile filtered2 = testUtils.addFileToProject(p, "folder1/folder2/filtered.txt", "");
+		IFile unfiltered = testUtils.addFileToProject(p, "folder1/folder2/unfiltered.txt", "");
+
+		createFilter(p, EXCLUDE_ALL | FILES | INHERITABLE, "filtered.txt");
+		assertFalse("IFile should no longer exist after filtering.", filtered1.exists());
+		assertFalse("IFile should no longer exist after filtering.", filtered2.exists());
+		assertTrue("IFile should exist after filtering.", unfiltered.exists());
+
+		List<Entry> entries = walkTree();
+
+		assertThat(entries, hasItem(containerTreeEntry("Project-1/folder1/filtered.txt")));
+		assertThat(entries, hasItem(containerTreeEntry("Project-1/folder1/folder2/filtered.txt")));
+		assertThat(entries, hasItem(containerTreeEntry("Project-1/folder1/folder2/unfiltered.txt")));
+	}
+
+	@Test
+	public void directlyNestedProject() throws Exception {
+		IProject p = project.getProject();
+		testUtils.addFileToProject(p, "file.txt", "");
+
+		TestProject testProject2 = new TestProject(true, "Project-1/Project-2");
+		testUtils.addFileToProject(testProject2.getProject(), "project2.txt", "");
+
+		createFilter(p, EXCLUDE_ALL | FOLDERS, "Project-2");
+
+		List<Entry> entries = walkTree();
+
+		assertThat(entries, hasItem(containerTreeEntry("Project-1/file.txt")));
+		// Should be handled by container tree iterator because it exists, even
+		// when it's not returned by members() of Project-1.
+		assertThat(entries, hasItem(containerTreeEntry("Project-1/Project-2/project2.txt")));
+	}
+
+	@Test
+	public void nestedProject() throws Exception {
+		IProject p = project.getProject();
+		testUtils.addFileToProject(p, "folder1/file.txt", "");
+		testUtils.addFileToProject(p, "folder1/subfolder/filtered.txt", "");
+
+		TestProject testProject2 = new TestProject(true, "Project-1/folder1/subfolder/Project-2");
+		connectProject(testProject2.getProject());
+		IFile project2File = testUtils.addFileToProject(testProject2.getProject(), "project2.txt", "");
+		assertThat(project2File.getProject(), is(testProject2.getProject()));
+
+		createFilter(p.getFolder("folder1"), EXCLUDE_ALL | FOLDERS, "subfolder");
+		assertFalse("IFolder should be filtered",
+				p.getFolder(new Path("folder1/subfolder")).exists());
+
+		List<Entry> entries = walkTree();
+
+		assertThat(entries, hasItem(containerTreeEntry("Project-1/folder1/file.txt")));
+		assertThat(entries, hasItem(adaptableFileTreeEntry("Project-1/folder1/subfolder/filtered.txt")));
+		// Should be handled by container tree iterator again, because the project exists.
+		assertThat(entries, hasItem(containerTreeEntry("Project-1/folder1/subfolder/Project-2/project2.txt")));
+
+		testProject2.dispose();
+	}
+
+	private static void createFilter(IContainer container, int type, String regexFilterArguments) throws CoreException {
+		FileInfoMatcherDescription matcherDescription = new FileInfoMatcherDescription(
+				"org.eclipse.core.resources.regexFilterMatcher",
+				regexFilterArguments);
+		container.createFilter(type, matcherDescription, 0, null);
+	}
+
+	private void connectProject(IProject p) throws CoreException {
+		final ConnectProviderOperation operation = new ConnectProviderOperation(
+				p, gitDir);
+		operation.execute(null);
+	}
+
+	private List<Entry> walkTree() throws IOException {
+		TreeWalk treeWalk = new TreeWalk(repository);
+		ContainerTreeIterator tree = new ContainerTreeIterator(repository, project.getProject());
+		int treeIndex = treeWalk.addTree(tree);
+		treeWalk.setRecursive(true);
+		List<Entry> entries = new ArrayList<Entry>();
+		while (treeWalk.next()) {
+			AbstractTreeIterator it = treeWalk.getTree(treeIndex, AbstractTreeIterator.class);
+			Entry entry = new Entry(treeWalk.getPathString(), it.getClass());
+			entries.add(entry);
+		}
+		return entries;
+	}
+
+	private static Entry containerTreeEntry(String path) {
+		return new Entry(path, ContainerTreeIterator.class);
+	}
+
+	private static Entry adaptableFileTreeEntry(String path) {
+		return new Entry(path, AdaptableFileTreeIterator.class);
+	}
+
+	// Value object (case class).
+	private static class Entry {
+		private final String path;
+		private Class<? extends AbstractTreeIterator> iteratorClass;
+
+		public Entry(String path, Class<? extends AbstractTreeIterator> iteratorClass) {
+			this.path = path;
+			this.iteratorClass = iteratorClass;
+		}
+
+		@Override
+		public String toString() {
+			return path + " (" + iteratorClass.getSimpleName() + ")";
+		}
+
+		@Override
+		public int hashCode() {
+			final int prime = 31;
+			int result = 1;
+			result = prime * result
+					+ ((iteratorClass == null) ? 0 : iteratorClass.hashCode());
+			result = prime * result + ((path == null) ? 0 : path.hashCode());
+			return result;
+		}
+
+		@Override
+		public boolean equals(Object obj) {
+			if (this == obj)
+				return true;
+			if (obj == null)
+				return false;
+			if (getClass() != obj.getClass())
+				return false;
+			Entry other = (Entry) obj;
+			if (iteratorClass == null) {
+				if (other.iteratorClass != null)
+					return false;
+			} else if (!iteratorClass.equals(other.iteratorClass))
+				return false;
+			if (path == null) {
+				if (other.path != null)
+					return false;
+			} else if (!path.equals(other.path))
+				return false;
+			return true;
+		}
+	}
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/DualRepositoryTestCase.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/DualRepositoryTestCase.java
new file mode 100644
index 0000000..78913ab
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/DualRepositoryTestCase.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (C) 2010, 2012 Mathias Kinzler <mathias.kinzler@sap.com> and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.test;
+
+import java.io.File;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.op.ConnectProviderOperation;
+import org.junit.After;
+import org.junit.Before;
+
+public abstract class DualRepositoryTestCase {
+
+	protected TestUtils testUtils = new TestUtils();
+
+	protected TestRepository repository1;
+
+	protected TestRepository repository2;
+
+	protected IProject testProject;
+
+	@Before
+	public void beforeTestCase() throws Exception {
+		// ensure there are no shared Repository instances left
+		// when starting a new test
+		Activator.getDefault().getRepositoryCache().clear();
+	}
+
+	@After
+	public void afterTestCase() throws Exception {
+		Activator.getDefault().getRepositoryCache().clear();
+		if (repository1 != null)
+			repository1.dispose();
+		if (repository2 != null)
+			repository2.dispose();
+		if (testProject != null)
+			testProject.delete(false, false, null);
+		testUtils.deleteTempDirs();
+	}
+
+	protected IProject importProject(TestRepository repo, String projectName)
+			throws Exception {
+		IProject firstProject = ResourcesPlugin.getWorkspace().getRoot()
+				.getProject(projectName);
+		if (firstProject.exists())
+			firstProject.delete(false, null);
+		IProjectDescription desc = ResourcesPlugin.getWorkspace()
+				.newProjectDescription(projectName);
+		File parentFile = repo.getRepository().getWorkTree();
+		desc.setLocation(new Path(new File(parentFile, projectName).getPath()));
+		firstProject.create(desc, null);
+		firstProject.open(null);
+		ConnectProviderOperation cop = new ConnectProviderOperation(
+				firstProject, repo.getRepository().getDirectory());
+		cop.execute(null);
+		return firstProject;
+	}
+
+
+
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/EclipseGitProgressTransformerTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/EclipseGitProgressTransformerTest.java
new file mode 100644
index 0000000..1df5421
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/EclipseGitProgressTransformerTest.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (C) 2011, Adrian G&ouml;rler <adrian.goerler@sap.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.test;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.egit.core.internal.EclipseGitProgressTransformer;
+import org.eclipse.jgit.lib.ProgressMonitor;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
+
+@RunWith(MockitoJUnitRunner.class)
+public class EclipseGitProgressTransformerTest {
+
+	@Mock
+	IProgressMonitor eclipseMonitor;
+
+	ProgressMonitor classUnderTest;
+
+	@Before
+	public void setup() {
+		classUnderTest = new EclipseGitProgressTransformer(eclipseMonitor);
+	}
+
+	@Test
+	public void testUnboundedMonitor() {
+		final String title = "Title";
+
+		classUnderTest.beginTask(title, ProgressMonitor.UNKNOWN);
+		Mockito.verify(eclipseMonitor).subTask("Title");
+
+		classUnderTest.update(10);
+		classUnderTest.update(0);
+		Mockito.verify(eclipseMonitor, Mockito.times(1)).subTask("Title, 10");
+		classUnderTest.update(20);
+		Mockito.verify(eclipseMonitor).subTask("Title, 30");
+
+	}
+
+	@Test
+	public void testBoundedMonitor() {
+		final String title = "Title";
+
+		classUnderTest.beginTask(title, 50);
+		Mockito.verify(eclipseMonitor).subTask("Title");
+
+		classUnderTest.update(10);
+		classUnderTest.update(0);
+		Mockito.verify(eclipseMonitor, Mockito.times(1)).subTask("Title:                    20% (10/50)");
+		classUnderTest.update(20);
+		Mockito.verify(eclipseMonitor).subTask("Title:                    60% (30/50)");
+
+	}
+
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/GitProjectSetCapabilityTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/GitProjectSetCapabilityTest.java
new file mode 100644
index 0000000..44c642a
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/GitProjectSetCapabilityTest.java
@@ -0,0 +1,321 @@
+/*******************************************************************************
+ * Copyright (C) 2011, 2012 Robin Stocker <robin@nibor.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.GitProjectSetCapability;
+import org.eclipse.egit.core.internal.RepositoryUtil;
+import org.eclipse.egit.core.internal.op.ConnectProviderOperation;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.lib.ConfigConstants;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.internal.storage.file.FileRepository;
+import org.eclipse.jgit.util.FileUtils;
+import org.eclipse.team.core.ProjectSetSerializationContext;
+import org.eclipse.team.core.TeamException;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class GitProjectSetCapabilityTest {
+
+	private GitProjectSetCapability capability;
+
+	private List<IProject> createdProjects = new ArrayList<IProject>();
+	private List<File> pathsToClean = new ArrayList<File>();
+
+	@Before
+	public void setUp() {
+		Activator.getDefault().getRepositoryCache().clear();
+		capability = new GitProjectSetCapability();
+	}
+
+	@After
+	public void tearDown() throws Exception {
+		Activator.getDefault().getRepositoryCache().clear();
+		for (IProject project : createdProjects)
+			if (project.exists())
+				project.delete(true, true, null);
+		for (File pathToClean : pathsToClean)
+			if (pathToClean.exists())
+				FileUtils.delete(pathToClean, FileUtils.RECURSIVE | FileUtils.RETRY);
+	}
+
+	@Test
+	public void testExport() throws Exception {
+		IProject aProject = createProject("a");
+		File aRepo = createRepository(aProject.getLocation(), "http://example.org/repo-a", "master");
+		connectProject(aProject, aRepo);
+
+		IPath bPath = ResourcesPlugin.getWorkspace().getRoot().getLocation().append("b");
+		File bRepo = createRepository(bPath, "http://example.org/repo-b", "master");
+		IProject baProject = createProject(bPath, "ba");
+		IProject bbProject = createProject(bPath, "bb");
+		connectProject(baProject, bRepo);
+		connectProject(bbProject, bRepo);
+		pathsToClean.add(bPath.toFile());
+
+		IProject cProject = createProject("c");
+		File cRepo = createRepository(cProject.getLocation(), "http://example.org/repo-c", "stable");
+		connectProject(cProject, cRepo);
+
+		IProject[] projects = new IProject[] { aProject, baProject, bbProject, cProject };
+		String[] references = capability.asReference(
+				projects, new ProjectSetSerializationContext(), new NullProgressMonitor());
+		assertEquals(4, references.length);
+		assertEquals("1.0,http://example.org/repo-a,master,.", references[0]);
+		assertEquals("1.0,http://example.org/repo-b,master,ba", references[1]);
+		assertEquals("1.0,http://example.org/repo-b,master,bb", references[2]);
+		assertEquals("1.0,http://example.org/repo-c,stable,.", references[3]);
+	}
+
+	@Test
+	public void testImport() throws Exception {
+		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+		IPath reposPath = root.getLocation().append("repos");
+		pathsToClean.add(reposPath.toFile());
+
+		IPath aPath = reposPath.append("a");
+		IProject aProject = createProject(reposPath, "a");
+		createRepository(aPath, "notused", "master");
+		aProject.delete(false, true, null);
+
+		IPath bPath = reposPath.append("b");
+		IProject baProject = createProject(bPath, "ba");
+		IProject bbProject = createProject(bPath, "bb");
+		createRepository(bPath, "notused", "master");
+		baProject.delete(false, true, null);
+		bbProject.delete(false, true, null);
+
+		IPath cPath = reposPath.append("c");
+		IProject cProject = createProject(reposPath, "c");
+		createRepository(cPath, "notused", "stable");
+		cProject.delete(false, true, null);
+
+		String aReference = "1.0," + aPath.toFile().toURI().toString() + ",master,.";
+		String baReference = "1.0," + bPath.toFile().toURI().toString() + ",master,ba";
+		String bbReference = "1.0," + bPath.toFile().toURI().toString() + ",master,bb";
+		String cReference = "1.0," + cPath.toFile().toURI().toString() + ",stable,.";
+		String[] references = new String[] { aReference, baReference, bbReference, cReference };
+
+		addToWorkspace(references);
+
+		pathsToClean.add(root.getLocation().append("b").toFile());
+
+		IProject aImported = root.getProject("a");
+		createdProjects.add(aImported);
+		assertTrue(aImported.exists());
+		assertNotNull(RepositoryMapping.getMapping(aImported));
+
+		IProject baImported = root.getProject("ba");
+		createdProjects.add(baImported);
+		assertTrue(baImported.exists());
+		assertEquals(root.getLocation().append("b/ba"), baImported.getLocation());
+		assertNotNull(RepositoryMapping.getMapping(baImported));
+
+		IProject bbImported = root.getProject("bb");
+		createdProjects.add(bbImported);
+		assertTrue(bbImported.exists());
+		assertEquals(root.getLocation().append("b/bb"), bbImported.getLocation());
+		assertNotNull(RepositoryMapping.getMapping(bbImported));
+
+		IProject cImported = root.getProject("c");
+		createdProjects.add(cImported);
+		assertTrue(cImported.exists());
+		RepositoryMapping cMapping = RepositoryMapping.getMapping(cImported);
+		assertNotNull(cMapping);
+		assertEquals("stable", cMapping.getRepository().getBranch());
+	}
+
+	@Test
+	public void testImportWithDifferentBranchesOfSameRepo() throws Exception {
+		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+		IPath reposPath = root.getLocation().append("repos");
+		pathsToClean.add(reposPath.toFile());
+
+		IPath xPath = reposPath.append("x");
+		IProject xaProject = createProject(xPath, "xa");
+		IProject xbProject = createProject(xPath, "xb");
+		createRepository(xPath, "notused", "stable");
+		xaProject.delete(false, true, null);
+		xbProject.delete(false, true, null);
+
+		String xaMasterReference = "1.0," + xPath.toFile().toURI().toString() + ",master,xa";
+		String xbStableReference = "1.0," + xPath.toFile().toURI().toString() + ",stable,xb";
+		String[] references = new String[] { xaMasterReference, xbStableReference };
+
+		addToWorkspace(references);
+
+		pathsToClean.add(root.getLocation().append("x").toFile());
+		pathsToClean.add(root.getLocation().append("x_stable").toFile());
+
+		IProject xaImported = root.getProject("xa");
+		createdProjects.add(xaImported);
+		assertTrue(xaImported.exists());
+		assertEquals(root.getLocation().append("x/xa"), xaImported.getLocation());
+		RepositoryMapping xaMapping = RepositoryMapping.getMapping(xaImported);
+		assertNotNull(xaMapping);
+		assertEquals("master", xaMapping.getRepository().getBranch());
+
+		IProject xbImported = root.getProject("xb");
+		createdProjects.add(xbImported);
+		assertTrue(xbImported.exists());
+		assertEquals(root.getLocation().append("x_stable/xb"), xbImported.getLocation());
+		RepositoryMapping xbMapping = RepositoryMapping.getMapping(xbImported);
+		assertNotNull(xbMapping);
+		assertEquals("stable", xbMapping.getRepository().getBranch());
+	}
+
+	@Test
+	public void testImportWithMultipleCallsForSameDestinationRepo() throws Exception {
+		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+		IPath reposPath = root.getLocation().append("repos");
+		pathsToClean.add(reposPath.toFile());
+
+		IPath xPath = reposPath.append("x");
+		IProject xaProject = createProject(xPath, "xa");
+		IProject xbProject = createProject(xPath, "xb");
+		String url = createUrl(xPath);
+		createRepository(xPath, url, "stable");
+		xaProject.delete(false, true, null);
+		xbProject.delete(false, true, null);
+
+		String xaReference = createProjectReference(xPath, "master", "xa");
+		String xbReference = createProjectReference(xPath, "master", "xb");
+
+		// This should work because there is not yet a repo at the destination
+		addToWorkspace(new String[] { xaReference });
+
+		// This should work because the repo that is already there is for the
+		// same remote URL. It's assumed to be ok and will skip cloning and
+		// directly import the project.
+		addToWorkspace(new String[] { xbReference });
+
+		pathsToClean.add(root.getLocation().append("x").toFile());
+
+		IPath otherPathWithX = reposPath.append("other").append("x");
+		String otherReferenceWithDifferentUrl = createProjectReference(otherPathWithX, "master", "xb");
+
+		try {
+			capability.addToWorkspace(new String[] { otherReferenceWithDifferentUrl },
+					new ProjectSetSerializationContext(),
+					new NullProgressMonitor());
+			fail("Should throw TeamException when a repo exists at the place but doesn't have the same URL.");
+		} catch (TeamException e) {
+			// This is expected
+		}
+	}
+
+	@Test
+	public void testImportWhereRepoAlreadyExistsAtDifferentLocation() throws Exception {
+		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+		IPath reposPath = root.getLocation().append("existingbutdifferent");
+		pathsToClean.add(reposPath.toFile());
+
+		IPath repoPath = reposPath.append("repo");
+		IProject project = createProject(repoPath, "project");
+		project.delete(false, true, null);
+		String url = createUrl(repoPath);
+		File repoDir = createRepository(repoPath, url, "master");
+
+		IPath otherRepoPath = reposPath.append("other");
+		File otherRepoDir = createRepository(otherRepoPath, "other-url", "master");
+
+		RepositoryUtil util = Activator.getDefault().getRepositoryUtil();
+		util.addConfiguredRepository(repoDir);
+		util.addConfiguredRepository(otherRepoDir);
+
+		String reference = createProjectReference(repoPath, "master", "project");
+
+		addToWorkspace(new String[] { reference });
+
+		IProject imported = root.getProject("project");
+		assertEquals("Expected imported project to be from already existing repository",
+				root.getLocation().append("existingbutdifferent/repo/project"), imported.getLocation());
+	}
+
+	private IProject createProject(String name) throws CoreException {
+		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+		IProject p = root.getProject(name);
+		p.create(null);
+		p.open(null);
+
+		createdProjects.add(p);
+		return p;
+	}
+
+	private IProject createProject(IPath parentLocation, String name) throws CoreException {
+		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+
+		IProject p = root.getProject(name);
+		IProjectDescription projectDescription = ResourcesPlugin.getWorkspace().newProjectDescription(p.getName());
+		projectDescription.setLocation(parentLocation.append(name));
+		p.create(projectDescription, null);
+		p.open(null);
+
+		createdProjects.add(p);
+		return p;
+	}
+
+	private File createRepository(IPath location, String url, String branch) throws Exception {
+		File gitDirectory = new File(location.toFile(), Constants.DOT_GIT);
+		Repository repo = new FileRepository(gitDirectory);
+		repo.getConfig().setString(ConfigConstants.CONFIG_REMOTE_SECTION, "origin", ConfigConstants.CONFIG_KEY_URL, url);
+		repo.getConfig().setString(ConfigConstants.CONFIG_BRANCH_SECTION, branch, ConfigConstants.CONFIG_KEY_REMOTE, "origin");
+		repo.create();
+		repo.close();
+
+		Git git = new Git(repo);
+		git.add().addFilepattern(".").call();
+		git.commit().setMessage("initial").call();
+		if (!branch.equals("master"))
+			git.checkout().setName(branch).setCreateBranch(true).call();
+
+		pathsToClean.add(gitDirectory);
+		return gitDirectory;
+	}
+
+	private void connectProject(IProject project, File gitDir) throws CoreException {
+		ConnectProviderOperation operation = new ConnectProviderOperation(
+				project.getProject(), gitDir);
+		operation.execute(null);
+	}
+
+	private static String createProjectReference(IPath repoPath, String branch, String projectPath) {
+		return "1.0," + createUrl(repoPath) + "," + branch + "," + projectPath;
+	}
+
+	private static String createUrl(IPath repoPath) {
+		return repoPath.toFile().toURI().toString();
+	}
+
+	private void addToWorkspace(String[] references) throws TeamException {
+		capability.addToWorkspace(references,
+				new ProjectSetSerializationContext(),
+				new NullProgressMonitor());
+	}
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/GitResourceDeltaTestHelper.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/GitResourceDeltaTestHelper.java
new file mode 100644
index 0000000..6f166c6
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/GitResourceDeltaTestHelper.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (C) 2013, François Rey <eclipse.org_@_francois_._rey_._name>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    François Rey - First implementation as part of handling linked resources
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.test;
+
+import static org.hamcrest.Matchers.hasItem;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
+import java.util.Collection;
+import java.util.HashSet;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IResourceDeltaVisitor;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.indexdiff.GitResourceDeltaVisitor;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.jgit.lib.Repository;
+
+/**
+ * Helper class for test cases that need to know what workspace changes egit
+ * will detect. Changes to files within the git repository folder are ignored
+ * by default, however this behavior can be changed by a constructor parameter.
+ * Usage: create one instance per test case and call {@link #setUp()} and
+ * {@link #tearDown()} before and after the test case. Use other functions
+ * to test and assert what changed resources are expected.
+ * Implementation is mainly an {@link IResourceChangeListener} which calls
+ * a {@link GitResourceDeltaVisitor} for each change that occurs in a project
+ * that uses egit.
+ */
+public class GitResourceDeltaTestHelper {
+	private Repository repository;
+
+	private IResourceChangeListener resourceChangeListener;
+
+	private final Collection<IResource> changedResources;
+
+	private final boolean ignoreTeamPrivateMember;
+
+	public GitResourceDeltaTestHelper(Repository repository) {
+		this(repository, true);
+	}
+
+	public GitResourceDeltaTestHelper(Repository repository,
+			boolean ignoreTeamPrivateMember) {
+		this.repository = repository;
+		this.changedResources = new HashSet<IResource>();
+		this.ignoreTeamPrivateMember = ignoreTeamPrivateMember;
+	}
+
+	public void setUp() {
+		resourceChangeListener = new IResourceChangeListener() {
+			public void resourceChanged(final IResourceChangeEvent event) {
+				try {
+					event.getDelta().accept(new IResourceDeltaVisitor() {
+						public boolean visit(IResourceDelta delta)
+								throws CoreException {
+							final IResource resource = delta.getResource();
+							IProject project = resource.getProject();
+							if (project == null)
+								return true;
+							RepositoryMapping mapping = RepositoryMapping
+									.getMapping(resource);
+							if (mapping == null)
+								return true;
+							if (mapping.getRepository() != repository)
+								return false;
+							GitResourceDeltaVisitor visitor = new GitResourceDeltaVisitor(
+									repository);
+							try {
+								event.getDelta().accept(visitor);
+							} catch (CoreException e) {
+								Activator.logError(e.getMessage(), e);
+								return false;
+							}
+							IPath gitDirAbsolutePath = mapping
+									.getGitDirAbsolutePath();
+							for (IResource res : visitor.getResourcesToUpdate()) {
+								if (ignoreTeamPrivateMember
+										&& (res.isTeamPrivateMember() || gitDirAbsolutePath
+												.isPrefixOf(res
+														.getRawLocation()
+														.makeAbsolute())))
+									continue;
+								changedResources.add(res);
+							}
+							return false;
+						}
+					});
+				} catch (CoreException e) {
+					Activator.logError(e.getMessage(), e);
+					return;
+				}
+			}
+		};
+		ResourcesPlugin.getWorkspace().addResourceChangeListener(
+				resourceChangeListener, IResourceChangeEvent.POST_CHANGE);
+	}
+
+	public void tearDown() {
+		if (resourceChangeListener != null) {
+			ResourcesPlugin.getWorkspace().removeResourceChangeListener(
+					resourceChangeListener);
+			resourceChangeListener = null;
+		}
+	}
+
+	public Collection<IResource> getChangedResources() {
+		return changedResources;
+	}
+
+	public boolean noChangedResources() {
+		return changedResources.isEmpty();
+	}
+
+	public boolean anyChangedResources() {
+		return !changedResources.isEmpty();
+	}
+
+	public void assertChangedResources(String[] expected) {
+		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+		for (String file : expected)
+			assertThat(changedResources, hasItem(root.findMember(file)));
+		assertEquals(expected.length, changedResources.size());
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/GitTestCase.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/GitTestCase.java
new file mode 100644
index 0000000..6e99a20
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/GitTestCase.java
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * Copyright (C) 2007, 2013 Robin Rosenberg <robin.rosenberg@dewire.com> and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.test;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.GitCorePreferences;
+import org.eclipse.jgit.junit.MockSystemReader;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.ObjectInserter;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.util.FileUtils;
+import org.eclipse.jgit.util.IO;
+import org.eclipse.jgit.util.SystemReader;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+
+public abstract class GitTestCase {
+
+	protected final TestUtils testUtils = new TestUtils();
+
+	protected TestProject project;
+
+	protected File gitDir;
+
+	@BeforeClass
+	public static void setUpClass() {
+		// suppress auto-ignoring and auto-sharing to avoid interference
+		IEclipsePreferences p = InstanceScope.INSTANCE.getNode(Activator
+				.getPluginId());
+		p.putBoolean(GitCorePreferences.core_autoIgnoreDerivedResources, false);
+		p.putBoolean(GitCorePreferences.core_autoShareProjects, false);
+	}
+
+	@Before
+	public void setUp() throws Exception {
+		// ensure there are no shared Repository instances left
+		// when starting a new test
+		Activator.getDefault().getRepositoryCache().clear();
+		MockSystemReader mockSystemReader = new MockSystemReader();
+		SystemReader.setInstance(mockSystemReader);
+		mockSystemReader.setProperty(Constants.GIT_CEILING_DIRECTORIES_KEY,
+				ResourcesPlugin.getWorkspace().getRoot().getLocation().toFile()
+						.getAbsoluteFile().toString());
+		project = new TestProject(true);
+		gitDir = new File(project.getProject().getWorkspace().getRoot()
+				.getRawLocation().toFile(), Constants.DOT_GIT);
+		if (gitDir.exists())
+			FileUtils.delete(gitDir, FileUtils.RECURSIVE | FileUtils.RETRY);
+	}
+
+	@After
+	public void tearDown() throws Exception {
+		project.dispose();
+		Activator.getDefault().getRepositoryCache().clear();
+		if (gitDir.exists())
+			FileUtils.delete(gitDir, FileUtils.RECURSIVE | FileUtils.RETRY);
+	}
+
+	protected ObjectId createFile(Repository repository, IProject actProject, String name, String content) throws IOException {
+		File file = new File(actProject.getProject().getLocation().toFile(), name);
+		FileWriter fileWriter = new FileWriter(file);
+		fileWriter.write(content);
+		fileWriter.close();
+		byte[] fileContents = IO.readFully(file);
+		ObjectInserter inserter = repository.newObjectInserter();
+		try {
+			ObjectId objectId = inserter.insert(Constants.OBJ_BLOB, fileContents);
+			inserter.flush();
+			return objectId;
+		} finally {
+			inserter.release();
+		}
+	}
+
+	protected ObjectId createFileCorruptShort(Repository repository,
+			IProject actProject, String name, String content)
+			throws IOException {
+		ObjectId id = createFile(repository, actProject, name, content);
+		File file = new File(repository.getDirectory(), "objects/"
+				+ id.name().substring(0, 2) + "/" + id.name().substring(2));
+		byte[] readFully = IO.readFully(file);
+		FileUtils.delete(file);
+		FileOutputStream fileOutputStream = new FileOutputStream(file);
+		byte[] truncatedData = new byte[readFully.length - 1];
+		System.arraycopy(readFully, 0, truncatedData, 0, truncatedData.length);
+		fileOutputStream.write(truncatedData);
+		fileOutputStream.close();
+		return id;
+	}
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/GitURITest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/GitURITest.java
new file mode 100644
index 0000000..08c02db
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/GitURITest.java
@@ -0,0 +1,199 @@
+/*******************************************************************************
+ * Copyright (c) 2011, IBM Corporation
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Tomasz Zarna (IBM) - initial implementation
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.test;
+
+import static org.junit.Assert.assertEquals;
+
+import java.net.URI;
+import java.util.HashMap;
+
+import org.eclipse.egit.core.internal.GitProjectSetCapability;
+import org.eclipse.egit.core.internal.GitURI;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.transport.URIish;
+import org.junit.Before;
+import org.junit.Test;
+
+public class GitURITest {
+
+	private GitProjectSetCapability capability;
+
+	@Before
+	public void setUp() {
+		capability = new GitProjectSetCapability();
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void testInvalidScmUriWithQuotationMarks() throws Exception {
+		URI.create("scm:git:git://git.eclipse.org/gitroot/platform/eclipse.platform.team.git;path=\"bundles/org.eclipse.team.core\"");
+		// expected IAE, " are not allowed in a URI reference
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void testInvalidScmUriForCVS() throws Exception {
+		new GitURI(URI.create("scm:cvs:pserver:dev.eclipse.org:/cvsroot/eclipse:org.eclipse.compare"));
+		// expected IAE, it's a CVS SCM URL
+	}
+
+	// ScmUrlImportDescription can handle " in Strings expected to be URI refs
+	@Test
+	public void testScmUriWithPath() throws Exception {
+		ScmUrlImportDescription description = new ScmUrlImportDescription(
+				"scm:git:git://git.eclipse.org/gitroot/platform/eclipse.platform.team.git;path=\"bundles/org.eclipse.team.core\"",
+				null);
+		URI uri = description.getUri();
+		GitURI gitUri = new GitURI(uri);
+		assertEquals("bundles/org.eclipse.team.core", gitUri.getPath()
+				.toString());
+		URIish uriish = new URIish(
+				"git://git.eclipse.org/gitroot/platform/eclipse.platform.team.git");
+		assertEquals(uriish, gitUri.getRepository());
+		assertEquals(Constants.MASTER, gitUri.getTag());
+
+		String refString = capability.asReference(uri, "org.eclipse.team.core");
+		assertEquals(
+				"1.0,git://git.eclipse.org/gitroot/platform/eclipse.platform.team.git,master,bundles/org.eclipse.team.core",
+				refString);
+	}
+
+	@Test
+	public void testScmUriWithPathAndTag() throws Exception {
+		ScmUrlImportDescription description = new ScmUrlImportDescription(
+				"scm:git:git://git.eclipse.org/gitroot/platform/eclipse.platform.ui.git;path=\"bundles/org.eclipse.jface\";tag=v20111107-2125",
+				null);
+		URI uri = description.getUri();
+		GitURI gitUri = new GitURI(uri);
+		assertEquals("bundles/org.eclipse.jface", gitUri.getPath().toString());
+		URIish uriish = new URIish(
+				"git://git.eclipse.org/gitroot/platform/eclipse.platform.ui.git");
+		assertEquals(uriish, gitUri.getRepository());
+		assertEquals("v20111107-2125", gitUri.getTag());
+
+		String refString = capability.asReference(uri, "org.eclipse.jface");
+		assertEquals(
+				"1.0,git://git.eclipse.org/gitroot/platform/eclipse.platform.ui.git,v20111107-2125,bundles/org.eclipse.jface",
+				refString);
+	}
+
+	@Test
+	public void testScmUriWithPathProjectAndTag() throws Exception {
+		ScmUrlImportDescription description = new ScmUrlImportDescription(
+				"scm:git:git://git.eclipse.org/gitroot/equinox/rt.equinox.bundles.git;path=\"bundles/org.eclipse.equinox.http.jetty6\";project=\"org.eclipse.equinox.http.jetty\";tag=v20111010-1614",
+				null);
+		URI uri = description.getUri();
+		GitURI gitUri = new GitURI(uri);
+		assertEquals("bundles/org.eclipse.equinox.http.jetty6", gitUri
+				.getPath().toString());
+		URIish uriish = new URIish(
+				"git://git.eclipse.org/gitroot/equinox/rt.equinox.bundles.git");
+		assertEquals(uriish, gitUri.getRepository());
+		assertEquals("v20111010-1614", gitUri.getTag());
+		assertEquals("org.eclipse.equinox.http.jetty", gitUri.getProjectName());
+
+		String refString = capability.asReference(uri,
+				"org.eclipse.equinox.http.jetty");
+		assertEquals(
+				"1.0,git://git.eclipse.org/gitroot/equinox/rt.equinox.bundles.git,v20111010-1614,bundles/org.eclipse.equinox.http.jetty6",
+				refString);
+	}
+
+	// TODO remove this copy of org.eclipse.team.core.ScmUrlImportDescription
+	// when we drop support for Galileo
+	/**
+	 * Copy of org.eclipse.team.core.ScmUrlImportDescription to support tests until
+	 * we drop support for Galileo. DON'T USE OUTSIDE OF TEST BUNDLE!
+	 *
+	 * Describes how a bundle import will be executed. A bundle importer delegate
+	 * creates bundle import descriptions when it validates bundle manifests for
+	 * importing. The result, a set of bundle import descriptions is then passed to
+	 * TeamUI, which basing on the info from the descriptions instantiate and
+	 * initialize IScmUrlImportWizardPage pages. The pages can be used to alter the
+	 * default import configuration e.g. for bundles stored in a CVS repository the
+	 * user may want to check out HEAD rather than a specific version.
+	 * <p>
+	 * <strong>EXPERIMENTAL</strong>. This class has been added as part of a work in
+	 * progress. There is no guarantee that this API will work or that it will
+	 * remain the same. Please do not use this API without consulting with the Team
+	 * team.
+	 *
+	 * @since 3.6
+	 */
+	protected static class ScmUrlImportDescription {
+		private String url;
+		private String project;
+		private HashMap properties;
+
+		public ScmUrlImportDescription(String url, String project) {
+			this.url = url;
+			this.project = project;
+		}
+
+		/**
+		 * @return project name
+		 */
+		public String getProject() {
+			return project;
+		}
+
+		/**
+		 * SCM URL
+		 *
+		 * @return a string representation of the SCM URL
+		 */
+		public String getUrl() {
+			return url;
+		}
+
+		public URI getUri() {
+			return URI.create(url.replaceAll("\"", "")); //$NON-NLS-1$//$NON-NLS-2$
+		}
+
+		public void setUrl(String url) {
+			this.url = url;
+		}
+
+		/**
+		 * Sets or removes a client property.
+		 *
+		 * @param key
+		 *            property key
+		 * @param value
+		 *            property value or <code>null</code> to remove the property
+		 */
+		public synchronized void setProperty(String key, Object value) {
+			if (properties == null) {
+				properties = new HashMap();
+			}
+			if (value == null) {
+				properties.remove(key);
+			} else {
+				properties.put(key, value);
+			}
+
+		}
+
+		/**
+		 * Returns the specified client property, or <code>null</code> if none.
+		 *
+		 * @param key
+		 *            property key
+		 * @return property value or <code>null</code>
+		 */
+		public synchronized Object getProperty(String key) {
+			if (properties == null) {
+				return null;
+			}
+			return properties.get(key);
+		}
+	}
+
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/JobSchedulingAssert.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/JobSchedulingAssert.java
new file mode 100644
index 0000000..659ed89
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/JobSchedulingAssert.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (C) 2012, Robin Stocker <robin@nibor.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.test;
+
+import static org.junit.Assert.assertTrue;
+
+import org.eclipse.core.runtime.jobs.IJobChangeEvent;
+import org.eclipse.core.runtime.jobs.IJobManager;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.core.runtime.jobs.JobChangeAdapter;
+
+/**
+ * Utility for testing if a job for a specific family has been scheduled.
+ * <p>
+ * Must be created before the test code is run, and then tested afterwards using
+ * {@link #assertScheduled(String)}.
+ * <p>
+ * This is more robust than using {@link IJobManager#find(Object)} after running
+ * the test code because it registers a listener and is not prone to the job
+ * being done already at the time of calling <code>find</code>.
+ */
+public class JobSchedulingAssert extends JobChangeAdapter {
+
+	private final Object jobFamily;
+
+	private boolean scheduled = false;
+
+	public static JobSchedulingAssert forFamily(Object jobFamily) {
+		return new JobSchedulingAssert(jobFamily);
+	}
+
+	private JobSchedulingAssert(Object jobFamily) {
+		this.jobFamily = jobFamily;
+		Job.getJobManager().addJobChangeListener(this);
+	}
+
+	@Override
+	public void scheduled(IJobChangeEvent event) {
+		if (event.getJob().belongsTo(jobFamily))
+			scheduled = true;
+	}
+
+	/**
+	 * Assert that the job has indeed been scheduled.
+	 *
+	 * @param messageForFailure
+	 *            message for when the assertion should fail
+	 */
+	public void assertScheduled(String messageForFailure) {
+		Job.getJobManager().removeJobChangeListener(this);
+		assertTrue(messageForFailure, scheduled);
+	}
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/LinkedResourcesTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/LinkedResourcesTest.java
new file mode 100644
index 0000000..58b9073
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/LinkedResourcesTest.java
@@ -0,0 +1,187 @@
+/*******************************************************************************
+ * Copyright (C) 2013, François Rey <eclipse.org_@_francois_._rey_._name>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    François Rey - First implementation as part of handling linked resources
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.ContainerTreeIterator;
+import org.eclipse.egit.core.internal.GitProvider;
+import org.eclipse.egit.core.internal.IteratorService;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.treewalk.WorkingTreeIterator;
+import org.eclipse.team.core.RepositoryProvider;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class LinkedResourcesTest {
+
+	TestUtils testUtils;
+
+	File project1Dir;
+
+	File project2Dir;
+
+	TestRepository repository1;
+
+	TestRepository repository2;
+
+	String project1Name = "project1";
+
+	String project2Name = "project2";
+
+	IProject project1;
+
+	IProject project2;
+
+	GitResourceDeltaTestHelper resourceDeltaTestHelper1;
+
+	GitResourceDeltaTestHelper resourceDeltaTestHelper2;
+
+	@Before
+	public void setUp() throws Exception {
+		testUtils = new TestUtils();
+		// Create first repo and project
+		project1 = testUtils.createProjectInLocalFileSystem(project1Name);
+		project1Dir = project1.getRawLocation().toFile();
+		repository1 = new TestRepository(new File(project1Dir,
+				Constants.DOT_GIT));
+		testUtils.addFileToProject(project1,
+				"project1folder1/project1folder1file1.txt", "Hello world");
+		repository1.connect(project1);
+		repository1.trackAllFiles(project1);
+		repository1.commit("Initial commit");
+		// Create 2nd repo and project
+		project2 = testUtils.createProjectInLocalFileSystem(project2Name);
+		project2Dir = project2.getRawLocation().toFile();
+		repository2 = new TestRepository(new File(project2Dir,
+				Constants.DOT_GIT));
+		testUtils.addFileToProject(project2,
+				"project2folder1/project2folder1file1.txt", "Hello world");
+		repository2.connect(project2);
+		repository2.trackAllFiles(project2);
+		repository2.commit("Initial commit");
+		// Set up git delta listener
+		resourceDeltaTestHelper1 = new GitResourceDeltaTestHelper(
+				repository1.getRepository());
+		resourceDeltaTestHelper1.setUp();
+		resourceDeltaTestHelper2 = new GitResourceDeltaTestHelper(
+				repository2.getRepository());
+		resourceDeltaTestHelper2.setUp();
+	}
+
+	@After
+	public void tearDown() throws Exception {
+		if (resourceDeltaTestHelper1 != null)
+			resourceDeltaTestHelper1.tearDown();
+		if (resourceDeltaTestHelper2 != null)
+			resourceDeltaTestHelper2.tearDown();
+		project1.delete(true, null);
+		project2.delete(true, null);
+		project1 = null;
+		project2 = null;
+		repository1.dispose();
+		repository2.dispose();
+		repository1 = null;
+		repository2 = null;
+		testUtils.deleteTempDirs();
+		testUtils = null;
+		Activator.getDefault().getRepositoryCache().clear();
+	}
+
+	@Test
+	public void testGitProviderCanHandleLinkedResources() throws Exception {
+		GitProvider provider = (GitProvider) RepositoryProvider
+				.getProvider(project1);
+		assertTrue(provider.canHandleLinkedResourceURI());
+	}
+
+	@Test
+	public void testLinkedResourcesIgnoredByGitResourceDeltaVisitor()
+			throws Exception {
+		// Create linked folder in project1 that points to project2
+		IFolder folder = project1.getFolder("link2project2");
+		folder.createLink(project2.getLocation(),
+				IResource.ALLOW_MISSING_LOCAL, null);
+		// Create linked file in project1 that points to a file in project2
+		IFile file = project1.getFile("link2project2folder1file1.txt");
+		file.createLink(
+				project2.getFile("project2folder1/project2folder1file1.txt")
+						.getLocation(), IResource.ALLOW_MISSING_LOCAL, null);
+		// Add file to project2
+		testUtils.addFileToProject(project2,
+				"project2folder1/project2folder1file2.txt", "Hello world");
+		// Links are written to the .project file
+		resourceDeltaTestHelper1
+				.assertChangedResources(new String[] { "/project1/.project" });
+		// Changes to linked resources are reported against their repository
+		resourceDeltaTestHelper2.assertChangedResources(new String[] {
+						"/project1/link2project2/project2folder1",
+						"/project1/link2project2/project2folder1/project2folder1file2.txt",
+						"/project1/link2project2/.project",
+						"/project1/link2project2/project2folder1/project2folder1file1.txt",
+						"/project1/link2project2",
+				"/project2/project2folder1/project2folder1file2.txt" });
+	}
+
+	@Test
+	public void testLinkedResourcesIgnoredByIteratorService() throws Exception {
+		// Create linked folder in project1 that points to project2
+		IFolder folder = project1.getFolder("link2project2");
+		folder.createLink(project2.getLocation(),
+				IResource.ALLOW_MISSING_LOCAL, null);
+		// Linked resources are ignored when searching the container of a folder
+		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+		IContainer container = IteratorService.findContainer(root, folder
+				.getRawLocation().makeAbsolute().toFile());
+		assertTrue(project2.equals(container));
+		// Also test when the only project left is the one linking to the folder
+		repository2.disconnect(project2);
+		container = IteratorService.findContainer(root, folder.getRawLocation()
+				.makeAbsolute().toFile());
+		assertNull(container);
+	}
+
+	@Test
+	public void testLinkedResourcesIgnoredByContainerTreeIterator()
+			throws Exception {
+		// Create linked folder in project1 that points to project2
+		IFolder folder = project1.getFolder("link2project2");
+		folder.createLink(project2.getLocation(),
+				IResource.ALLOW_MISSING_LOCAL, null);
+		// Create linked file in project1 that points to a file in project2
+		IFile file = project1.getFile("link2project2folder1file1.txt");
+		file.createLink(
+				project2.getFile("project2folder1/project2folder1file1.txt")
+						.getLocation(), IResource.ALLOW_MISSING_LOCAL, null);
+		// Test iterator
+		WorkingTreeIterator iterator = IteratorService
+				.createInitialIterator(repository1.repository);
+		assertTrue(iterator instanceof ContainerTreeIterator);
+		while (!iterator.eof()) {
+			assertFalse(iterator.getEntryPathString().startsWith("link2"));
+			iterator.next(1);
+		}
+	}
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/ProjectReferenceTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/ProjectReferenceTest.java
new file mode 100644
index 0000000..402a440
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/ProjectReferenceTest.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (C) 2011, Manuel Doninger <manuel.doninger@googlemail.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.net.URISyntaxException;
+
+import org.eclipse.egit.core.internal.ProjectReference;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ProjectReferenceTest {
+
+	private String version = "1.0";
+	private String url = "git://egit.eclipse.org/egit.git";
+	private String branch = "master";
+	private String project = "org.eclipse.egit.core";
+	private ProjectReference projectReference;
+
+	@Before
+	public void createProjectReferenceFromString() throws IllegalArgumentException, URISyntaxException {
+		String reference = version + "," + url + "," + branch + "," + project;
+		projectReference = new ProjectReference(reference);
+		assertNotNull(projectReference);
+	}
+
+	@Test
+	public void checkUrl() {
+		assertEquals(url, projectReference.getRepository().toString());
+	}
+
+	@Test
+	public void checkBranch() {
+		assertEquals(branch, projectReference.getBranch());
+	}
+
+	@Test
+	public void checkProject() {
+		assertEquals(project, projectReference.getProjectDir());
+	}
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/RepositoryCacheTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/RepositoryCacheTest.java
new file mode 100644
index 0000000..e663a6b
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/RepositoryCacheTest.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Red Hat, Inc. Distributed under license by Red Hat, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Andre Dietisheim - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.isIn;
+import static org.hamcrest.core.IsNot.not;
+
+import java.io.IOException;
+
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.RepositoryCache;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.util.FileUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class RepositoryCacheTest extends GitTestCase {
+
+	private TestRepository testRepository;
+	private Repository repository;
+	private RepositoryCache cache;
+
+	@Before
+	public void setUp() throws Exception {
+		super.setUp();
+		this.testRepository = new TestRepository(gitDir);
+		this.repository = testRepository.getRepository();
+		this.cache = Activator.getDefault().getRepositoryCache();
+	}
+
+	@After
+	public void tearDown() throws Exception {
+		testRepository.dispose();
+		repository = null;
+		super.tearDown();
+	}
+
+	@Test
+	public void shouldNotContainDeletedRepository() throws IOException {
+		cache.lookupRepository(repository.getDirectory());
+		assertThat(repository, isIn(cache.getAllRepositories()));
+		FileUtils.delete(repository.getDirectory(), FileUtils.RECURSIVE);
+		assertThat(repository, not(isIn(cache.getAllRepositories())));
+	}
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/RevUtilsTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/RevUtilsTest.java
new file mode 100644
index 0000000..c9fa582
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/RevUtilsTest.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (C) 2012, Robin Stocker <robin@nibor.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.util.Collection;
+
+import org.eclipse.egit.core.internal.RevUtils;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class RevUtilsTest extends GitTestCase {
+
+	private TestRepository testRepository;
+	private Repository repository;
+
+	@Before
+	public void setUp() throws Exception {
+		super.setUp();
+		testRepository = new TestRepository(gitDir);
+		repository = testRepository.getRepository();
+	}
+
+	@After
+	public void tearDown() throws Exception {
+		testRepository.dispose();
+		repository = null;
+		super.tearDown();
+	}
+
+	@Test
+	public void isContainedInAnyRef() throws Exception {
+		RevCommit first = testRepository.createInitialCommit("First commit");
+		testRepository.createBranch("refs/heads/master", "refs/heads/other");
+		assertFalse(isContainedInAnyRemoteRef(first));
+
+		testRepository.createBranch("refs/heads/master", "refs/remotes/origin/a");
+		assertTrue(isContainedInAnyRemoteRef(first));
+
+		RevCommit second = testRepository.commit("Second commit");
+		assertFalse(isContainedInAnyRemoteRef(second));
+
+		testRepository.createBranch("refs/heads/master", "refs/remotes/origin/b");
+		assertTrue(isContainedInAnyRemoteRef(second));
+
+		RevCommit third = testRepository.commit("Third commit");
+		testRepository.commit("Fourth commit");
+		testRepository.createBranch("refs/heads/master", "refs/remotes/origin/c");
+		assertTrue(isContainedInAnyRemoteRef(third));
+	}
+
+	private boolean isContainedInAnyRemoteRef(RevCommit commit) throws IOException {
+		Collection<Ref> remoteRefs = repository.getRefDatabase().getRefs(Constants.R_REMOTES).values();
+		return RevUtils.isContainedInAnyRef(repository, commit, remoteRefs);
+	}
+
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/TestProject.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/TestProject.java
new file mode 100644
index 0000000..56c0ea4
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/TestProject.java
@@ -0,0 +1,294 @@
+/*******************************************************************************
+ * Copyright (C) 2007, Robin Rosenberg <robin.rosenberg@dewire.com>
+ * Copyright (C) 2006, Shawn O. Pearce <spearce@spearce.org>
+ * Copyright (C) 2012, Robin Stocker <robin@nibor.org>
+ * Copyright (C) 2013, Matthias Sohn <matthias.sohn@sap.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.test;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URL;
+
+import org.eclipse.core.filesystem.URIUtil;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.launching.JavaRuntime;
+import org.eclipse.jgit.util.FileUtils;
+import org.osgi.framework.Bundle;
+
+public class TestProject {
+	public IProject project;
+
+	public IJavaProject javaProject;
+
+	private IPackageFragmentRoot sourceFolder;
+	private String location;
+	private TestUtils testUtils = new TestUtils();
+
+	private final File workspaceSupplement;
+
+	private IFolder binFolder;
+
+	/**
+	 * @throws CoreException
+	 *             If project already exists
+	 */
+	public TestProject() throws CoreException {
+		this(false);
+	}
+
+	public TestProject(boolean remove) throws CoreException {
+		this(remove, "Project-1");
+	}
+
+	/**
+	 * @param remove
+	 *            should project be removed if already exists
+	 * @param path
+	 * @throws CoreException
+	 */
+	public TestProject(final boolean remove, String path) throws CoreException {
+		this(remove, path, true, null);
+	}
+
+	/**
+	 * @param remove
+	 *            should project be removed if already exists
+	 * @param path
+	 * @param insidews set false to create in temp
+	 * @param workspaceSupplement
+	 * @throws CoreException
+	 */
+	public TestProject(final boolean remove, String path, boolean insidews, File workspaceSupplement) throws CoreException {
+		this.workspaceSupplement = workspaceSupplement;
+		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+		IProjectDescription description = createDescription(path, insidews,
+				root, workspaceSupplement);
+		project = root.getProject(description.getName());
+		if (remove)
+			project.delete(true, null);
+		IPath locationBefore = description.getLocation();
+		if (locationBefore == null)
+			locationBefore = root.getRawLocation().append(path);
+		location = locationBefore.toOSString();
+		project.create(description, null);
+		project.open(null);
+		javaProject = JavaCore.create(project);
+		binFolder = createBinFolder();
+		setJavaNature();
+		javaProject.setRawClasspath(new IClasspathEntry[0], null);
+		createOutputFolder(binFolder);
+		addSystemLibraries();
+	}
+
+	public void setBinFolderDerived() throws CoreException {
+		binFolder.setDerived(true, null);
+	}
+
+	public File getWorkspaceSupplement() {
+		return workspaceSupplement;
+	}
+
+	private IProjectDescription createDescription(String path,
+			boolean insidews, IWorkspaceRoot root, File workspaceSupplement) {
+		Path ppath = new Path(path);
+		String projectName = ppath.lastSegment();
+		URI locationURI;
+		URI top;
+		if (insidews) {
+			top = root.getRawLocationURI();
+		} else {
+			top = URIUtil.toURI(workspaceSupplement.getAbsolutePath());
+		}
+		if (!insidews || !ppath.lastSegment().equals(path)) {
+			locationURI = URIUtil.toURI(URIUtil.toPath(top).append(path));
+		} else
+			locationURI = null;
+		IProjectDescription description = ResourcesPlugin.getWorkspace()
+				.newProjectDescription(projectName);
+
+		description.setName(projectName);
+		description.setLocationURI(locationURI);
+		return description;
+	}
+
+	public IProject getProject() {
+		return project;
+	}
+
+	public IJavaProject getJavaProject() {
+		return javaProject;
+	}
+
+	public void addJar(String plugin, String jar) throws JavaModelException {
+		Path result = findFileInPlugin(plugin, jar);
+		IClasspathEntry[] oldEntries = javaProject.getRawClasspath();
+		IClasspathEntry[] newEntries = new IClasspathEntry[oldEntries.length + 1];
+		System.arraycopy(oldEntries, 0, newEntries, 0, oldEntries.length);
+		newEntries[oldEntries.length] = JavaCore.newLibraryEntry(result, null,
+				null);
+		javaProject.setRawClasspath(newEntries, null);
+	}
+
+	public IPackageFragment createPackage(String name) throws CoreException {
+		if (sourceFolder == null)
+			sourceFolder = createSourceFolder();
+		return sourceFolder.createPackageFragment(name, false, null);
+	}
+
+	public IType createType(IPackageFragment pack, String cuName, String source)
+			throws JavaModelException {
+		StringBuilder buf = new StringBuilder();
+		buf.append("package " + pack.getElementName() + ";\n");
+		buf.append("\n");
+		buf.append(source);
+		ICompilationUnit cu = pack.createCompilationUnit(cuName,
+				buf.toString(), false, null);
+		return cu.getTypes()[0];
+	}
+
+	public IFile createFile(String name, byte[] content) throws Exception {
+		IFile file = project.getFile(name);
+		InputStream inputStream = new ByteArrayInputStream(content);
+		file.create(inputStream, true, null);
+
+		return file;
+	}
+
+	public IFolder createFolder(String name) throws Exception {
+		IFolder folder = project.getFolder(name);
+		folder.create(true, true, null);
+		return folder;
+	}
+
+	public IFolder createFolderWithKeep(String name) throws Exception {
+		IFolder folder = createFolder(name);
+
+		IFile keep = project.getFile(name + "/keep");
+		keep.create(new ByteArrayInputStream(new byte[] {0}), true, null);
+
+		return folder;
+	}
+
+	public void dispose() throws CoreException, IOException {
+		waitForIndexer();
+		if (project.exists())
+			project.delete(true, true, null);
+		else {
+			File f = new File(location);
+			if (f.exists())
+				FileUtils.delete(f, FileUtils.RECURSIVE | FileUtils.RETRY);
+		}
+	}
+
+	private IFolder createBinFolder() throws CoreException {
+		IFolder binFolder = project.getFolder("bin");
+		binFolder.create(false, true, null);
+		return binFolder;
+	}
+
+	private void setJavaNature() throws CoreException {
+		IProjectDescription description = project.getDescription();
+		description.setNatureIds(new String[] { JavaCore.NATURE_ID });
+		project.setDescription(description, null);
+	}
+
+	private void createOutputFolder(IFolder binFolder)
+			throws JavaModelException {
+		IPath outputLocation = binFolder.getFullPath();
+		javaProject.setOutputLocation(outputLocation, null);
+	}
+
+	public IPackageFragmentRoot createSourceFolder() throws CoreException {
+		IFolder folder = project.getFolder("src");
+		folder.create(false, true, null);
+		IPackageFragmentRoot root = javaProject.getPackageFragmentRoot(folder);
+		IClasspathEntry[] oldEntries = javaProject.getRawClasspath();
+		IClasspathEntry[] newEntries = new IClasspathEntry[oldEntries.length + 1];
+		System.arraycopy(oldEntries, 0, newEntries, 0, oldEntries.length);
+		newEntries[oldEntries.length] = JavaCore.newSourceEntry(root.getPath());
+		javaProject.setRawClasspath(newEntries, null);
+		return root;
+	}
+
+	private void addSystemLibraries() throws JavaModelException {
+		IClasspathEntry[] oldEntries = javaProject.getRawClasspath();
+		IClasspathEntry[] newEntries = new IClasspathEntry[oldEntries.length + 1];
+		System.arraycopy(oldEntries, 0, newEntries, 0, oldEntries.length);
+		newEntries[oldEntries.length] = JavaRuntime
+				.getDefaultJREContainerEntry();
+		javaProject.setRawClasspath(newEntries, null);
+	}
+
+	private Path findFileInPlugin(String plugin, String file) {
+		Bundle bundle = Platform.getBundle(plugin);
+		URL resource = bundle.getResource(file);
+		return new Path(resource.getPath());
+	}
+
+	public void waitForIndexer() {
+		//                new SearchEngine().searchAllTypeNames(ResourcesPlugin.getWorkspace(),
+		//                                null, null, IJavaSearchConstants.EXACT_MATCH,
+		//                                IJavaSearchConstants.CASE_SENSITIVE,
+		//                                IJavaSearchConstants.CLASS, SearchEngine
+		//                                                .createJavaSearchScope(new IJavaElement[0]),
+		//                                new ITypeNameRequestor() {
+		//                                        public void acceptClass(char[] packageName,
+		//                                                        char[] simpleTypeName, char[][] enclosingTypeNames,
+		//                                                        String path) {
+		//                                        }
+		//                                        public void acceptInterface(char[] packageName,
+		//                                                        char[] simpleTypeName, char[][] enclosingTypeNames,
+		//                                                        String path) {
+		//                                        }
+		//                                }, IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH, null);
+	}
+
+	public String getFileContent(String filepath) throws Exception {
+		IFile file = project.getFile(filepath);
+		InputStream stream = file.getContents();
+		return testUtils.slurpAndClose(stream);
+	}
+	/**
+	 * @return Returns the sourceFolder.
+	 */
+	public IPackageFragmentRoot getSourceFolder() {
+		return sourceFolder;
+	}
+
+	/**
+	 * @param sourceFolder The sourceFolder to set.
+	 */
+	public void setSourceFolder(IPackageFragmentRoot sourceFolder) {
+		this.sourceFolder = sourceFolder;
+	}
+
+	public String getLocation() {
+		return location;
+	}
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/TestRepository.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/TestRepository.java
new file mode 100644
index 0000000..558a486
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/TestRepository.java
@@ -0,0 +1,545 @@
+/*******************************************************************************
+ * Copyright (C) 2011, Mathias Kinzler <mathias.kinzler@sap.com>
+ * Copyright (C) 2010, Jens Baumgart <jens.baumgart@sap.com>
+ * Copyright (C) 2012, Robin Stocker <robin@nibor.org>
+ * Copyright (C) 2012, François Rey <eclipse.org_@_francois_._rey_._name>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.test;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.regex.Pattern;
+
+import org.eclipse.core.filesystem.EFS;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceVisitor;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.op.BranchOperation;
+import org.eclipse.egit.core.internal.op.ConnectProviderOperation;
+import org.eclipse.egit.core.internal.op.DisconnectProviderOperation;
+import org.eclipse.jgit.api.CommitCommand;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.ConcurrentRefUpdateException;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.api.errors.JGitInternalException;
+import org.eclipse.jgit.api.errors.NoFilepatternException;
+import org.eclipse.jgit.api.errors.NoHeadException;
+import org.eclipse.jgit.api.errors.NoMessageException;
+import org.eclipse.jgit.api.errors.WrongRepositoryStateException;
+import org.eclipse.jgit.dircache.DirCache;
+import org.eclipse.jgit.dircache.DirCacheEntry;
+import org.eclipse.jgit.errors.UnmergedPathException;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.RefUpdate;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.internal.storage.file.FileRepository;
+import org.eclipse.jgit.transport.URIish;
+import org.eclipse.jgit.treewalk.TreeWalk;
+import org.eclipse.jgit.util.FileUtils;
+
+/**
+ * Helper class for creating and filling a test repository
+ *
+ */
+public class TestRepository {
+
+	Repository repository;
+
+	String workdirPrefix;
+
+	/**
+	 * Creates a new test repository
+	 *
+	 * @param gitDir
+	 * @throws IOException
+	 */
+	public TestRepository(File gitDir) throws IOException {
+		FileRepository tmpRepository = new FileRepository(gitDir);
+		tmpRepository.create();
+		tmpRepository.close();
+		// use repository instance from RepositoryCache!
+		repository = Activator.getDefault().getRepositoryCache().lookupRepository(gitDir);
+		try {
+			workdirPrefix = repository.getWorkTree().getCanonicalPath();
+		} catch (IOException err) {
+			workdirPrefix = repository.getWorkTree().getAbsolutePath();
+		}
+		workdirPrefix = workdirPrefix.replace('\\', '/');
+		if (!workdirPrefix.endsWith("/")) //$NON-NLS-1$
+			workdirPrefix += "/"; //$NON-NLS-1$
+	}
+
+	/**
+	 * Creates a test repository from an existing Repository
+	 *
+	 * @param repository
+	 * @throws IOException
+	 */
+	public TestRepository(Repository repository) throws IOException {
+		this.repository = repository;
+		try {
+			workdirPrefix = repository.getWorkTree().getCanonicalPath();
+		} catch (IOException err) {
+			workdirPrefix = repository.getWorkTree().getAbsolutePath();
+		}
+		workdirPrefix = workdirPrefix.replace('\\', '/');
+		if (!workdirPrefix.endsWith("/")) //$NON-NLS-1$
+			workdirPrefix += "/"; //$NON-NLS-1$
+	}
+
+	/**
+	 * @return the wrapped repository
+	 */
+	public Repository getRepository() {
+		return repository;
+	}
+
+	/**
+	 * create an initial commit containing a file "dummy" in the
+	 *
+	 * @param message
+	 *            commit message
+	 * @return commit object
+	 * @throws IOException
+	 * @throws JGitInternalException
+	 * @throws GitAPIException
+	 * @throws NoFilepatternException
+	 */
+	public RevCommit createInitialCommit(String message) throws IOException,
+			JGitInternalException, NoFilepatternException, GitAPIException {
+		String repoPath = repository.getWorkTree().getAbsolutePath();
+		File file = new File(repoPath, "dummy");
+		if (!file.exists())
+			FileUtils.createNewFile(file);
+		track(file);
+		return commit(message);
+	}
+
+	/**
+	 * Create a file or get an existing one
+	 *
+	 * @param project
+	 *            instance of project inside with file will be created
+	 * @param name
+	 *            name of file
+	 * @return nearly created file
+	 * @throws IOException
+	 */
+	public File createFile(IProject project, String name) throws IOException {
+		String path = project.getLocation().append(name).toOSString();
+		int lastSeparator = path.lastIndexOf(File.separator);
+		FileUtils.mkdirs(new File(path.substring(0, lastSeparator)), true);
+
+		File file = new File(path);
+		if (!file.exists())
+			FileUtils.createNewFile(file);
+
+		return file;
+	}
+
+	/**
+	 * Track, add to index and finally commit given file
+	 *
+	 * @param project
+	 * @param file
+	 * @param commitMessage
+	 * @return commit object
+	 * @throws Exception
+	 */
+	public RevCommit addAndCommit(IProject project, File file, String commitMessage)
+			throws Exception {
+		track(file);
+		addToIndex(project, file);
+
+		return commit(commitMessage);
+	}
+
+	/**
+	 * Appends file content to given file, then track, add to index and finally
+	 * commit it.
+	 *
+	 * @param project
+	 * @param file
+	 * @param content
+	 * @param commitMessage
+	 * @return commit object
+	 * @throws Exception
+	 */
+	public RevCommit appendContentAndCommit(IProject project, File file,
+			byte[] content, String commitMessage) throws Exception {
+		return appendContentAndCommit(project, file, new String(content),
+				commitMessage);
+	}
+
+	/**
+	 * Appends file content to given file, then track, add to index and finally
+	 * commit it.
+	 *
+	 * @param project
+	 * @param file
+	 * @param content
+	 * @param commitMessage
+	 * @return commit object
+	 * @throws Exception
+	 */
+	public RevCommit appendContentAndCommit(IProject project, File file,
+			String content, String commitMessage) throws Exception {
+		appendFileContent(file, content);
+		track(file);
+		addToIndex(project, file);
+
+		return commit(commitMessage);
+	}
+
+	/**
+	 * Commits the current index
+	 *
+	 * @param message
+	 *            commit message
+	 * @return commit object
+	 *
+	 * @throws NoHeadException
+	 * @throws NoMessageException
+	 * @throws UnmergedPathException
+	 * @throws ConcurrentRefUpdateException
+	 * @throws JGitInternalException
+	 * @throws GitAPIException
+	 * @throws WrongRepositoryStateException
+	 */
+	public RevCommit commit(String message) throws NoHeadException,
+			NoMessageException, UnmergedPathException,
+			ConcurrentRefUpdateException, JGitInternalException,
+			WrongRepositoryStateException, GitAPIException {
+		Git git = new Git(repository);
+		CommitCommand commitCommand = git.commit();
+		commitCommand.setAuthor("J. Git", "j.git@egit.org");
+		commitCommand.setCommitter(commitCommand.getAuthor());
+		commitCommand.setMessage(message);
+		return commitCommand.call();
+	}
+
+	/**
+	 * Adds file to version control
+	 *
+	 * @param file
+	 * @throws IOException
+	 * @throws GitAPIException
+	 * @throws NoFilepatternException
+	 */
+	public void track(File file) throws IOException, NoFilepatternException, GitAPIException {
+		String repoPath = getRepoRelativePath(new Path(file.getPath())
+				.toString());
+		new Git(repository).add().addFilepattern(repoPath).call();
+	}
+
+	/**
+	 * Adds all project files to version control
+	 *
+	 * @param project
+	 * @throws CoreException
+	 */
+	public void trackAllFiles(IProject project) throws CoreException {
+		project.accept(new IResourceVisitor() {
+
+			public boolean visit(IResource resource) throws CoreException {
+				if (resource instanceof IFile) {
+					try {
+						track(EFS.getStore(resource.getLocationURI())
+										.toLocalFile(0, null));
+					} catch (Exception e) {
+						throw new CoreException(Activator.error(e.getMessage(),
+								e));
+					}
+				}
+				return true;
+			}
+		});
+	}
+
+	/**
+	 * Removes file from version control
+	 *
+	 * @param file
+	 * @throws IOException
+	 */
+	public void untrack(File file) throws IOException {
+		String repoPath = getRepoRelativePath(new Path(file.getPath())
+				.toString());
+		try {
+			new Git(repository).rm().addFilepattern(repoPath).call();
+		} catch (GitAPIException e) {
+			throw new IOException(e.getMessage());
+		}
+	}
+
+	/**
+	 * Creates a new branch and immediately checkout it.
+	 *
+	 * @param refName
+	 *            starting point for the new branch
+	 * @param newRefName
+	 * @throws Exception
+	 */
+	public void createAndCheckoutBranch(String refName, String newRefName) throws Exception {
+		createBranch(refName, newRefName);
+		checkoutBranch(newRefName);
+	}
+
+	/**
+	 * Creates a new branch
+	 *
+	 * @param refName
+	 *            starting point for the new branch
+	 * @param newRefName
+	 * @throws IOException
+	 */
+	public void createBranch(String refName, String newRefName)
+			throws IOException {
+		RefUpdate updateRef;
+		updateRef = repository.updateRef(newRefName);
+		Ref startRef = repository.getRef(refName);
+		ObjectId startAt = repository.resolve(refName);
+		String startBranch;
+		if (startRef != null)
+			startBranch = refName;
+		else
+			startBranch = startAt.name();
+		startBranch = Repository.shortenRefName(startBranch);
+		updateRef.setNewObjectId(startAt);
+		updateRef
+				.setRefLogMessage("branch: Created from " + startBranch, false); //$NON-NLS-1$
+		updateRef.update();
+	}
+
+	/**
+	 * Checkouts branch
+	 *
+	 * @param refName
+	 *            full name of branch
+	 * @throws CoreException
+	 */
+	public void checkoutBranch(String refName) throws CoreException {
+		new BranchOperation(repository, refName).execute(null);
+	}
+
+	/**
+	 * Adds the given file to the index
+	 *
+	 * @param project
+	 * @param file
+	 * @throws Exception
+	 */
+	public void addToIndex(IProject project, File file) throws Exception {
+		IFile iFile = getIFile(project, file);
+		addToIndex(iFile);
+	}
+
+
+	/**
+	 * Adds the given resource to the index
+	 *
+	 * @param resource
+	 * @throws CoreException
+	 * @throws IOException
+	 * @throws GitAPIException
+	 * @throws NoFilepatternException
+	 */
+	public void addToIndex(IResource resource) throws CoreException, IOException, NoFilepatternException, GitAPIException {
+		String repoPath = getRepoRelativePath(resource.getLocation().toOSString());
+		new Git(repository).add().addFilepattern(repoPath).call();
+	}
+
+	/**
+	 * Appends content to end of given file.
+	 *
+	 * @param file
+	 * @param content
+	 * @throws IOException
+	 */
+	public void appendFileContent(File file, byte[] content) throws IOException {
+		appendFileContent(file, new String(content), true);
+	}
+
+	/**
+	 * Appends content to end of given file.
+	 *
+	 * @param file
+	 * @param content
+	 * @throws IOException
+	 */
+	public void appendFileContent(File file, String content) throws IOException {
+		appendFileContent(file, content, true);
+	}
+
+	/**
+	 * Appends content to given file.
+	 *
+	 * @param file
+	 * @param content
+	 * @param append
+	 *            if true, then bytes will be written to the end of the file
+	 *            rather than the beginning
+	 * @throws IOException
+	 */
+	public void appendFileContent(File file, byte[] content, boolean append)
+			throws IOException {
+		appendFileContent(file, new String(content), append);
+	}
+
+	/**
+	 * Appends content to given file.
+	 *
+	 * @param file
+	 * @param content
+	 * @param append
+	 *            if true, then bytes will be written to the end of the file
+	 *            rather than the beginning
+	 * @throws IOException
+	 */
+	public void appendFileContent(File file, String content, boolean append)
+			throws IOException {
+		FileWriter fw = null;
+		try {
+			fw = new FileWriter(file, append);
+			fw.append(content);
+		} finally {
+			if (fw != null)
+				fw.close();
+		}
+	}
+
+	/**
+	 * Checks if a file with the given path exists in the HEAD tree
+	 *
+	 * @param path
+	 * @return true if the file exists
+	 * @throws IOException
+	 */
+	public boolean inHead(String path) throws IOException {
+		ObjectId headId = repository.resolve(Constants.HEAD);
+		RevWalk rw = new RevWalk(repository);
+		TreeWalk tw = null;
+		try {
+			tw = TreeWalk.forPath(repository, path, rw.parseTree(headId));
+			return tw != null;
+		} finally {
+			rw.release();
+			rw.dispose();
+			if (tw != null)
+				tw.release();
+		}
+	}
+
+	public boolean inIndex(String absolutePath) throws IOException {
+		return getDirCacheEntry(absolutePath) != null;
+	}
+
+	public boolean removedFromIndex(String absolutePath) throws IOException {
+		DirCacheEntry dc = getDirCacheEntry(absolutePath);
+		if (dc == null)
+			return true;
+
+		Ref ref = repository.getRef(Constants.HEAD);
+		RevCommit c = new RevWalk(repository).parseCommit(ref.getObjectId());
+		TreeWalk tw = TreeWalk.forPath(repository, getRepoRelativePath(absolutePath), c.getTree());
+
+		return tw == null || dc.getObjectId().equals(tw.getObjectId(0));
+	}
+
+	public long lastModifiedInIndex(String path) throws IOException {
+		String repoPath = getRepoRelativePath(path);
+		DirCache dc = DirCache.read(repository.getIndexFile(), repository.getFS());
+
+		return dc.getEntry(repoPath).getLastModified();
+	}
+
+	public int getDirCacheEntryLength(String path) throws IOException {
+		String repoPath = getRepoRelativePath(path);
+		DirCache dc = DirCache.read(repository.getIndexFile(), repository.getFS());
+
+		return dc.getEntry(repoPath).getLength();
+	}
+
+	public String getRepoRelativePath(String path) {
+		final int pfxLen = workdirPrefix.length();
+		final int pLen = path.length();
+		if (pLen > pfxLen)
+			return path.substring(pfxLen);
+		else if (path.length() == pfxLen - 1)
+			return ""; //$NON-NLS-1$
+		return null;
+	}
+
+	public IFile getIFile(IProject project, File file) throws CoreException {
+		String relativePath = getRepoRelativePath(file.getAbsolutePath());
+
+		String quotedProjectName = Pattern.quote(project.getName());
+		relativePath = relativePath.replaceFirst(quotedProjectName, "");
+
+		IFile iFile = project.getFile(relativePath);
+		iFile.refreshLocal(0, null);
+
+		return iFile;
+	}
+
+	public void dispose() {
+		if (repository != null) {
+			repository.close();
+			repository = null;
+		}
+	}
+
+	/**
+	 * Connect a project to this repository
+	 *
+	 * @param project
+	 * @throws CoreException
+	 */
+	public void connect(IProject project) throws CoreException {
+		ConnectProviderOperation op = new ConnectProviderOperation(project,
+				this.getRepository().getDirectory());
+		op.execute(null);
+	}
+
+	/**
+	 * Disconnects provider from project
+	 *
+	 * @param project
+	 * @throws CoreException
+	 */
+	public void disconnect(IProject project) throws CoreException {
+		Collection<IProject> projects = Collections.singleton(project
+				.getProject());
+		DisconnectProviderOperation disconnect = new DisconnectProviderOperation(
+				projects);
+		disconnect.execute(null);
+	}
+
+	public URIish getUri() throws URISyntaxException {
+		return new URIish("file:///" + repository.getDirectory().toString());
+	}
+
+	private DirCacheEntry getDirCacheEntry(String path) throws IOException {
+		String repoPath = getRepoRelativePath(path);
+		DirCache dc = DirCache.read(repository.getIndexFile(), repository.getFS());
+
+		return dc.getEntry(repoPath);
+	}
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/TestUtils.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/TestUtils.java
new file mode 100644
index 0000000..e8d2dbe
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/TestUtils.java
@@ -0,0 +1,286 @@
+/*******************************************************************************
+ * Copyright (C) 2007, Robin Rosenberg <robin.rosenberg@dewire.com>
+ * Copyright (C) 2010, Jens Baumgart <jens.baumgart@sap.com>
+ * Copyright (C) 2010, Mathias Kinzler <mathias.kinzler@sap.com>
+ * Copyright (C) 2012, François Rey <eclipse.org_@_francois_._rey_._name>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.test;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.treewalk.TreeWalk;
+import org.eclipse.jgit.util.FS;
+import org.eclipse.jgit.util.FileUtils;
+
+public class TestUtils {
+
+	public final static String AUTHOR = "The Author <The.author@some.com>";
+
+	public final static String COMMITTER = "The Commiter <The.committer@some.com>";
+
+	/**
+	 * Return the base directory in which temporary directories are created.
+	 * Current implementation returns a "temporary" folder in the user home.
+	 *
+	 * @return a "temporary" folder in the user home that may not exist.
+	 * @throws IOException
+	 */
+	public File getBaseTempDir() throws IOException {
+		File userHome = FS.DETECTED.userHome();
+		File rootDir = new File(userHome, "EGitCoreTestTempDir");
+		return rootDir;
+	}
+
+	/**
+	 * Create a "temporary" directory
+	 *
+	 * @param name
+	 *            the name of the directory
+	 * @return a directory as child of a "temporary" folder in the user home
+	 *         directory; may or may not exist
+	 * @throws IOException
+	 */
+	public File createTempDir(String name) throws IOException {
+		File result = new File(getBaseTempDir(), name);
+		if (result.exists())
+			FileUtils.delete(result, FileUtils.RECURSIVE | FileUtils.RETRY);
+		return result;
+	}
+
+	/**
+	 * Cleanup: delete the "temporary" folder and all children
+	 *
+	 * @throws IOException
+	 */
+	public void deleteTempDirs() throws IOException {
+		File rootDir = getBaseTempDir();
+		if (rootDir.exists())
+			FileUtils.delete(rootDir, FileUtils.RECURSIVE | FileUtils.RETRY);
+	}
+
+	/**
+	 * Read the stream into a String
+	 *
+	 * @param inputStream
+	 * @return the contents of the stream
+	 * @throws IOException
+	 */
+	public String slurpAndClose(InputStream inputStream) throws IOException {
+		StringBuilder stringBuilder = new StringBuilder();
+		try {
+			int ch;
+			while ((ch = inputStream.read()) != -1) {
+				stringBuilder.append((char) ch);
+			}
+		} finally {
+			inputStream.close();
+		}
+		return stringBuilder.toString();
+	}
+
+	/**
+	 * Add a file to an existing project
+	 *
+	 * @param project
+	 *            the project
+	 * @param path
+	 *            e.g. "folder1/folder2/test.txt"
+	 * @param content
+	 *            the contents
+	 * @return the file
+	 * @throws CoreException
+	 *             if the file can not be created
+	 * @throws UnsupportedEncodingException
+	 */
+	public IFile addFileToProject(IProject project, String path, String content) throws CoreException, UnsupportedEncodingException {
+		IPath filePath = new Path(path);
+		IFolder folder = null;
+		for (int i = 0; i < filePath.segmentCount() - 1; i++) {
+			if (folder == null) {
+				folder = project.getFolder(filePath.segment(i));
+			} else {
+				folder = folder.getFolder(filePath.segment(i));
+			}
+			if (!folder.exists())
+				folder.create(false, true, null);
+		}
+		IFile file = project.getFile(filePath);
+		file.create(new ByteArrayInputStream(content.getBytes(project
+				.getDefaultCharset())), true, null);
+		return file;
+	}
+
+	/**
+	 * Change the content of a file
+	 *
+	 * @param project
+	 * @param file
+	 * @param newContent
+	 * @return the file
+	 * @throws CoreException
+	 * @throws UnsupportedEncodingException
+	 */
+	public IFile changeContentOfFile(IProject project, IFile file, String newContent) throws UnsupportedEncodingException, CoreException {
+		file.setContents(new ByteArrayInputStream(newContent.getBytes(project
+				.getDefaultCharset())), 0, null);
+		return file;
+	}
+
+	/**
+	 * Create a project in the base directory of temp dirs
+	 *
+	 * @param projectName
+	 *            project name
+	 * @return the project with a location pointing to the local file system
+	 * @throws Exception
+	 */
+	public IProject createProjectInLocalFileSystem(
+			String projectName) throws Exception {
+		return createProjectInLocalFileSystem(getBaseTempDir(), projectName);
+	}
+
+	/**
+	 * Create a project in the local file system
+	 *
+	 * @param parentFile
+	 *            the parent directory
+	 * @param projectName
+	 *            project name
+	 * @return the project with a location pointing to the local file system
+	 * @throws Exception
+	 */
+	public IProject createProjectInLocalFileSystem(File parentFile,
+			String projectName) throws Exception {
+		IProject project = ResourcesPlugin.getWorkspace().getRoot()
+				.getProject(projectName);
+		if (project.exists()) {
+			project.delete(true, null);
+		}
+		File testFile = new File(parentFile, projectName);
+		if (testFile.exists())
+			FileUtils.delete(testFile, FileUtils.RECURSIVE | FileUtils.RETRY);
+
+		IProjectDescription desc = ResourcesPlugin.getWorkspace()
+				.newProjectDescription(projectName);
+		desc.setLocation(new Path(new File(parentFile, projectName).getPath()));
+		project.create(desc, null);
+		project.open(null);
+		return project;
+	}
+
+	/**
+	 * verifies that repository contains exactly the given files.
+	 * @param repository
+	 * @param paths
+	 * @throws Exception
+	 */
+	public void assertRepositoryContainsFiles(Repository repository,
+			String[] paths) throws Exception {
+		Set<String> expectedfiles = new HashSet<String>();
+		for (String path : paths)
+			expectedfiles.add(path);
+		TreeWalk treeWalk = new TreeWalk(repository);
+		treeWalk.addTree(repository.resolve("HEAD^{tree}"));
+		treeWalk.setRecursive(true);
+		while (treeWalk.next()) {
+			String path = treeWalk.getPathString();
+			if (!expectedfiles.contains(path))
+				fail("Repository contains unexpected expected file " + path);
+			expectedfiles.remove(path);
+		}
+		if (expectedfiles.size() > 0) {
+			StringBuilder message = new StringBuilder(
+					"Repository does not contain expected files: ");
+			for (String path : expectedfiles) {
+				message.append(path);
+				message.append(" ");
+			}
+			fail(message.toString());
+		}
+	}
+
+	/**
+	 * verifies that repository contains exactly the given files with the given
+	 * content. Usage example:<br>
+	 *
+	 * <code>
+	 * assertRepositoryContainsFiles(repository, "foo/a.txt", "content of A",
+	 *                                           "foo/b.txt", "content of B")
+	 * </code>
+	 * @param repository
+	 * @param args
+	 * @throws Exception
+	 */
+	public void assertRepositoryContainsFilesWithContent(Repository repository,
+			String... args) throws Exception {
+		HashMap<String, String> expectedfiles = mkmap(args);
+		TreeWalk treeWalk = new TreeWalk(repository);
+		treeWalk.addTree(repository.resolve("HEAD^{tree}"));
+		treeWalk.setRecursive(true);
+		while (treeWalk.next()) {
+			String path = treeWalk.getPathString();
+			assertTrue(expectedfiles.containsKey(path));
+			ObjectId objectId = treeWalk.getObjectId(0);
+			byte[] expectedContent = expectedfiles.get(path).getBytes();
+			byte[] repoContent = treeWalk.getObjectReader().open(objectId)
+					.getBytes();
+			if (!Arrays.equals(repoContent, expectedContent)) {
+				fail("File " + path + " has repository content "
+						+ new String(repoContent)
+						+ " instead of expected content "
+						+ new String(expectedContent));
+			}
+			expectedfiles.remove(path);
+		}
+		if (expectedfiles.size() > 0) {
+			StringBuilder message = new StringBuilder(
+					"Repository does not contain expected files: ");
+			for (String path : expectedfiles.keySet()) {
+				message.append(path);
+				message.append(" ");
+			}
+			fail(message.toString());
+		}
+	}
+
+	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<String, String>();
+		for (int i = 0; i < args.length; i += 2) {
+			map.put(args[i], args[i+1]);
+		}
+		return map;
+	}
+
+	File getWorkspaceSupplement() throws IOException {
+		return createTempDir("wssupplement");
+	}
+
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/UtilsTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/UtilsTest.java
new file mode 100644
index 0000000..856f88a
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/UtilsTest.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (C) 2011, Jens Baumgart <jens.baumgart@sap.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.test;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.egit.core.internal.Utils;
+import org.junit.Test;
+
+public class UtilsTest {
+
+	@Test
+	public void testLineEndingNormalization() {
+		String str = "";
+		String result = Utils.normalizeLineEndings(str);
+		assertEquals(result, "");
+
+		str = "Line 1";
+		result = Utils.normalizeLineEndings(str);
+		assertEquals("Line 1", result);
+
+		str = "Line 1\r\nLine 2";
+		result = Utils.normalizeLineEndings(str);
+		assertEquals("Line 1\nLine 2", result);
+
+		str = "Line 1\r\nLine 2\r";
+		result = Utils.normalizeLineEndings(str);
+		assertEquals("Line 1\nLine 2\n", result);
+
+		str = "Line 1\r\nLine 2\nLine 3\rLine 4\r\nLine 5\rLine 6\r\n Line 7\r";
+		result = Utils.normalizeLineEndings(str);
+		assertEquals(
+				"Line 1\nLine 2\nLine 3\nLine 4\nLine 5\nLine 6\n Line 7\n",
+				result);
+	}
+
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/indexDiff/IndexDiffCacheTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/indexDiff/IndexDiffCacheTest.java
new file mode 100644
index 0000000..5e59a8b
--- /dev/null
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/test/indexDiff/IndexDiffCacheTest.java
@@ -0,0 +1,196 @@
+/*******************************************************************************
+ * Copyright (C) 2011, 2012 Jens Baumgart <jens.baumgart@sap.com> and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.test.indexDiff;
+
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.Matchers.hasItem;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.indexdiff.IndexDiffCache;
+import org.eclipse.egit.core.internal.indexdiff.IndexDiffCacheEntry;
+import org.eclipse.egit.core.internal.indexdiff.IndexDiffChangedListener;
+import org.eclipse.egit.core.internal.indexdiff.IndexDiffData;
+import org.eclipse.egit.core.internal.op.ConnectProviderOperation;
+import org.eclipse.egit.core.internal.test.GitTestCase;
+import org.eclipse.egit.core.internal.test.TestRepository;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.lib.Repository;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class IndexDiffCacheTest extends GitTestCase {
+
+	TestRepository testRepository;
+
+	Repository repository;
+
+	private AtomicBoolean listenerCalled;
+
+	private AtomicReference<IndexDiffData> indexDiffDataResult;
+
+	@Before
+	public void setUp() throws Exception {
+		super.setUp();
+		testRepository = new TestRepository(gitDir);
+		repository = testRepository.getRepository();
+	}
+
+	@After
+	public void tearDown() throws Exception {
+		testRepository.dispose();
+		repository = null;
+		super.tearDown();
+	}
+
+	@Test
+	public void testAddingAFile() throws Exception {
+		new ConnectProviderOperation(project.project, repository.getDirectory())
+				.execute(null);
+		// create first commit containing a dummy file
+		testRepository
+				.createInitialCommit("testBranchOperation\n\nfirst commit\n");
+		prepareCacheEntry();
+		waitForListenerCalled();
+		final String fileName = "aFile";
+		// This call should trigger an indexDiffChanged event (triggered via
+		// resource changed event)
+		project.createFile(fileName, "content".getBytes("UTF-8"));
+		IndexDiffData indexDiffData = waitForListenerCalled();
+		String path = project.project.getFile(fileName).getFullPath()
+				.toString().substring(1);
+		if (!indexDiffData.getUntracked().contains(path))
+			fail("IndexDiffData did not contain aFile as untracked");
+		// This call should trigger an indexDiffChanged event
+		new Git(repository).add().addFilepattern(path).call();
+		IndexDiffData indexDiffData2 = waitForListenerCalled();
+		if (indexDiffData2.getUntracked().contains(path))
+			fail("IndexDiffData contains aFile as untracked");
+		if (!indexDiffData2.getAdded().contains(path))
+			fail("IndexDiffData does not contain aFile as added");
+	}
+
+	@Test
+	public void testAddFileFromUntrackedFolder() throws Exception {
+		testRepository.connect(project.project);
+		testRepository.addToIndex(project.project);
+		testRepository.createInitialCommit("testAddFileFromUntrackedFolder\n\nfirst commit\n");
+		prepareCacheEntry();
+
+		project.createFolder("folder");
+		project.createFolder("folder/a");
+		project.createFolder("folder/b");
+		IFile fileA = project.createFile("folder/a/file", new byte[] {});
+		project.createFile("folder/b/file", new byte[] {});
+
+		IndexDiffData data1 = waitForListenerCalled();
+		assertThat(data1.getUntrackedFolders(), hasItem("Project-1/folder/"));
+
+		testRepository.track(fileA.getLocation().toFile());
+
+		IndexDiffData data2 = waitForListenerCalled();
+		assertThat(data2.getAdded(), hasItem("Project-1/folder/a/file"));
+		assertThat(data2.getUntrackedFolders(), not(hasItem("Project-1/folder/")));
+		assertThat(data2.getUntrackedFolders(), not(hasItem("Project-1/folder/a")));
+		assertThat(data2.getUntrackedFolders(), hasItem("Project-1/folder/b/"));
+	}
+
+	@Test
+	public void testAddIgnoredFolder() throws Exception {
+		testRepository.connect(project.project);
+		project.createFile(".gitignore", "ignore\n".getBytes("UTF-8"));
+		project.createFolder("ignore");
+		project.createFile("ignore/file.txt", new byte[] {});
+		project.createFolder("sub");
+		testRepository.addToIndex(project.project);
+		testRepository.createInitialCommit("testAddFileInIgnoredFolder\n\nfirst commit\n");
+		prepareCacheEntry();
+
+		IndexDiffData data1 = waitForListenerCalled();
+		assertThat(data1.getIgnoredNotInIndex(), hasItem("Project-1/ignore"));
+
+		project.createFolder("sub/ignore");
+
+		IndexDiffData data2 = waitForListenerCalled();
+		assertThat(data2.getIgnoredNotInIndex(), hasItem("Project-1/ignore"));
+		assertThat(data2.getIgnoredNotInIndex(), hasItem("Project-1/sub/ignore"));
+
+		// Must not change anything (ignored path starts with this string, but
+		// it's not a prefix path of it)
+		project.createFile("sub/ignorenot", new byte[] {});
+
+		IndexDiffData data3 = waitForListenerCalled();
+		assertThat(data3.getUntracked(), hasItem("Project-1/sub/ignorenot"));
+		assertThat(data3.getIgnoredNotInIndex(), hasItem("Project-1/ignore"));
+		assertThat(data3.getIgnoredNotInIndex(), hasItem("Project-1/sub/ignore"));
+	}
+
+	@Test
+	public void testRemoveIgnoredFile() throws Exception {
+		testRepository.connect(project.project);
+		project.createFile(".gitignore", "ignore\n".getBytes("UTF-8"));
+		project.createFolder("sub");
+		IFile file = project.createFile("sub/ignore", new byte[] {});
+		testRepository.addToIndex(project.project);
+		testRepository.createInitialCommit("testRemoveIgnoredFile\n\nfirst commit\n");
+		prepareCacheEntry();
+
+		IndexDiffData data1 = waitForListenerCalled();
+		assertThat(data1.getIgnoredNotInIndex(), hasItem("Project-1/sub/ignore"));
+
+		// Must not change anything (ignored path starts with this string, but
+		// it's not a prefix path of it)
+		project.createFile("sub/ignorenot", new byte[] {});
+
+		IndexDiffData data2 = waitForListenerCalled();
+		assertThat(data2.getIgnoredNotInIndex(), hasItem("Project-1/sub/ignore"));
+
+		file.delete(false, null);
+
+		IndexDiffData data3 = waitForListenerCalled();
+		assertThat(data3.getIgnoredNotInIndex(), not(hasItem("Project-1/sub/ignore")));
+	}
+
+	private void prepareCacheEntry() {
+		IndexDiffCache indexDiffCache = Activator.getDefault()
+				.getIndexDiffCache();
+		// This call should trigger an indexDiffChanged event
+		IndexDiffCacheEntry cacheEntry = indexDiffCache
+				.getIndexDiffCacheEntry(repository);
+		listenerCalled = new AtomicBoolean(false);
+		indexDiffDataResult = new AtomicReference<IndexDiffData>(
+				null);
+		cacheEntry.addIndexDiffChangedListener(new IndexDiffChangedListener() {
+			public void indexDiffChanged(Repository repo,
+					IndexDiffData indexDiffData) {
+				listenerCalled.set(true);
+				indexDiffDataResult.set(indexDiffData);
+			}
+		});
+	}
+
+	private IndexDiffData waitForListenerCalled() throws InterruptedException {
+		long time = 0;
+		while (!listenerCalled.get() && time < 60000) {
+			Thread.sleep(100);
+			time += 100;
+		}
+		assertTrue("indexDiffChanged was not called after " + time + " ms", listenerCalled.get());
+		listenerCalled.set(false);
+		return indexDiffDataResult.get();
+	}
+
+}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/util/ProjectUtilTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/util/ProjectUtilTest.java
index cc12e73..361b0e3 100644
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/util/ProjectUtilTest.java
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/util/ProjectUtilTest.java
@@ -32,10 +32,10 @@
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.egit.core.op.ConnectProviderOperation;
-import org.eclipse.egit.core.test.GitTestCase;
-import org.eclipse.egit.core.test.TestProject;
-import org.eclipse.egit.core.test.TestRepository;
+import org.eclipse.egit.core.internal.op.ConnectProviderOperation;
+import org.eclipse.egit.core.internal.test.GitTestCase;
+import org.eclipse.egit.core.internal.test.TestProject;
+import org.eclipse.egit.core.internal.test.TestRepository;
 import org.eclipse.jgit.util.FileUtils;
 import org.junit.After;
 import org.junit.Before;
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/util/ResourceUtilTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/util/ResourceUtilTest.java
index bde211b..2cfcfdb 100644
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/util/ResourceUtilTest.java
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/util/ResourceUtilTest.java
@@ -19,8 +19,8 @@
 import org.eclipse.core.resources.IFolder;
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.runtime.IPath;
-import org.eclipse.egit.core.test.GitTestCase;
-import org.eclipse.egit.core.test.TestProject;
+import org.eclipse.egit.core.internal.test.GitTestCase;
+import org.eclipse.egit.core.internal.test.TestProject;
 import org.junit.Test;
 
 public class ResourceUtilTest extends GitTestCase {
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/project/RepositoryMappingTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/project/RepositoryMappingTest.java
deleted file mode 100644
index 3262448..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/project/RepositoryMappingTest.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2012, 2013 Robin Stocker <robin@nibor.org> and others.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.project;
-
-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 org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IWorkspaceRoot;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.core.test.GitTestCase;
-import org.eclipse.egit.core.test.TestRepository;
-import org.eclipse.jgit.lib.Repository;
-import org.junit.Before;
-import org.junit.Test;
-
-public class RepositoryMappingTest extends GitTestCase {
-
-	private Repository repository;
-
-	@Before
-	@Override
-	public void setUp() throws Exception {
-		super.setUp();
-
-		TestRepository testRepo = new TestRepository(gitDir);
-		testRepo.connect(project.project);
-		repository = testRepo.getRepository();
-	}
-
-	@Test
-	public void shouldReturnMappingForResourceInProject() throws Exception {
-		IFile file = project.createFile("inproject.txt", new byte[] {});
-
-		RepositoryMapping mapping = RepositoryMapping.getMapping(file);
-
-		assertNotNull(mapping);
-		assertEquals(repository, mapping.getRepository());
-		assertEquals(project.getProject(), mapping.getContainer());
-		assertEquals(project.getProject().getName() + "/inproject.txt", mapping.getRepoRelativePath(file));
-	}
-
-	@Test
-	public void shouldNotReturnMappingForResourceOutsideOfProject() {
-		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
-		IPath filePath = getWorkTreePath().append("outside.txt");
-		IFile file = root.getFile(filePath);
-		assertFalse(file.exists());
-
-		RepositoryMapping mapping = RepositoryMapping.getMapping(file);
-
-		assertNull(mapping);
-	}
-
-	@Test
-	public void shouldReturnMappingForPathOutsideOfProject() {
-		IPath filePath = getWorkTreePath().append("outside.txt");
-
-		RepositoryMapping mapping = RepositoryMapping.getMapping(filePath);
-
-		assertNotNull(mapping);
-		assertEquals(repository, mapping.getRepository());
-		assertEquals("outside.txt", mapping.getRepoRelativePath(filePath));
-	}
-
-	@Test
-	public void shouldReturnMappingWhenPathIsRepository() {
-		IPath workTreePath = getWorkTreePath();
-
-		RepositoryMapping mapping = RepositoryMapping.getMapping(workTreePath);
-
-		assertNotNull(mapping);
-		assertEquals(repository, mapping.getRepository());
-		assertEquals("", mapping.getRepoRelativePath(workTreePath));
-	}
-
-	@Test
-	public void shouldNotReturnMappingWhenPathIsOutsideRepository() {
-		IPath workTreePath = getWorkTreePath();
-
-		assertNull(RepositoryMapping
-				.getMapping(new Path("D:/some/made/up/path")));
-		assertNull(RepositoryMapping.getMapping(new Path("/some/made/up/path")));
-		assertNull(RepositoryMapping.getMapping(new Path(
-				"/thereshouldnever/be/something/here")));
-
-		if (workTreePath.getDevice() == null)
-			assertNull(RepositoryMapping.getMapping(workTreePath
-					.setDevice("C:")));
-	}
-
-	@Test
-	public void shouldFindRepositoryMappingForRepository() {
-		RepositoryMapping mapping = RepositoryMapping.findRepositoryMapping(repository);
-
-		assertNotNull(mapping);
-		assertEquals(repository, mapping.getRepository());
-	}
-
-	private IPath getWorkTreePath() {
-		return new Path(repository.getWorkTree().getAbsolutePath());
-	}
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/securestorage/EGitSecureStoreTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/securestorage/EGitSecureStoreTest.java
deleted file mode 100644
index 8fec2e3..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/securestorage/EGitSecureStoreTest.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2010, Jens Baumgart <jens.baumgart@sap.com>
- * Copyright (C) 2010, Edwin Kempin <edwin.kempin@sap.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.securestorage;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.HashMap;
-
-import javax.crypto.spec.PBEKeySpec;
-
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.equinox.security.storage.ISecurePreferences;
-import org.eclipse.equinox.security.storage.SecurePreferencesFactory;
-import org.eclipse.equinox.security.storage.provider.IProviderHints;
-import org.eclipse.jgit.transport.URIish;
-import org.eclipse.jgit.util.FileUtils;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class EGitSecureStoreTest {
-
-	ISecurePreferences secureStoreForTest;
-
-	EGitSecureStore store;
-
-	@Before
-	public void setUp() throws Exception {
-		setupNewSecureStore();
-		store = new EGitSecureStore(secureStoreForTest);
-	}
-
-	@After
-	public void tearDown() throws Exception {
-		secureStoreForTest.flush();
-	}
-
-	@Test
-	public void testPutUserAndPassword() throws Exception {
-		URIish uri = new URIish("http://testRepo.example.com/testrepo");
-		UserPasswordCredentials credentials = new UserPasswordCredentials(
-				"agitter", "letmein");
-		store.putCredentials(uri, credentials);
-
-		ISecurePreferences node = secureStoreForTest.node(EGitSecureStore
-				.calcNodePath(uri).toString());
-		assertEquals("agitter", node.get("user", null));
-		assertTrue(node.isEncrypted("password"));
-		assertEquals("letmein", node.get("password", null));
-	}
-
-	@Test
-	public void testGetUserAndPassword() throws Exception {
-		URIish uri = new URIish("http://testRepo.example.com/testrepo");
-		UserPasswordCredentials credentials = new UserPasswordCredentials(
-				"agitter", "letmein");
-		store.putCredentials(uri, credentials);
-
-		UserPasswordCredentials storedCredentials = store.getCredentials(uri);
-		assertEquals("agitter", storedCredentials.getUser());
-		assertEquals("letmein", storedCredentials.getPassword());
-	}
-
-	@Test
-	public void testGetUserAndPasswordUnknownURI() throws Exception {
-		URIish uri = new URIish("http://testRepo.example.com/testrepo");
-
-		UserPasswordCredentials storedCredentials = store.getCredentials(uri);
-		assertNull(storedCredentials);
-	}
-
-	@Test
-	public void testPutUserAndPasswordURIContainingUserAndPass()
-			throws Exception {
-		URIish uri = new URIish(
-				"http://user:pass@testRepo.example.com/testrepo");
-		UserPasswordCredentials credentials = new UserPasswordCredentials(
-				"agitter", "letmein");
-		store.putCredentials(uri, credentials);
-
-		ISecurePreferences node = secureStoreForTest.node(EGitSecureStore
-				.calcNodePath(uri).toString());
-		assertEquals("agitter", node.get("user", null));
-		assertTrue(node.isEncrypted("password"));
-		assertEquals("letmein", node.get("password", null));
-	}
-
-	@Test
-	public void testGetUserAndPasswordURIContainingUserAndPass()
-			throws Exception {
-		store.putCredentials(
-				new URIish("http://testRepo.example.com/testrepo"),
-				new UserPasswordCredentials("agitter", "letmein"));
-		UserPasswordCredentials credentials = store.getCredentials(new URIish(
-				"http://agitter:letmein@testRepo.example.com/testrepo"));
-		assertEquals("agitter", credentials.getUser());
-		assertEquals("letmein", credentials.getPassword());
-	}
-
-	@Test
-	public void testGetUserAndPasswordURIContainingOtherUserAndPass()
-			throws Exception {
-		store.putCredentials(
-				new URIish("http://testRepo.example.com/testrepo"),
-				new UserPasswordCredentials("agitter", "letmein"));
-		assertNull(store.getCredentials(new URIish(
-				"http://otheruser:otherpass@testRepo.example.com/testrepo")));
-	}
-
-	@Test
-	public void testClearCredentials() throws Exception {
-		URIish uri = new URIish("http://testRepo.example.com/testrepo");
-		UserPasswordCredentials credentials = new UserPasswordCredentials(
-				"agitter", "letmein");
-		store.putCredentials(uri, credentials);
-		store.clearCredentials(uri);
-		assertEquals(null, store.getCredentials(uri));
-	}
-
-	@Test
-	public void testEnsureDefaultPortHttp() throws Exception {
-		URIish uri = new URIish("http://testRepo.example.com/testrepo");
-		UserPasswordCredentials credentials = new UserPasswordCredentials(
-				"agitter", "letmein");
-		store.putCredentials(uri, credentials);
-		URIish uri2 = new URIish("http://testRepo.example.com:80/testrepo");
-		assertEquals(credentials.getUser(), store.getCredentials(uri2).getUser());
-		assertEquals(credentials.getPassword(), store.getCredentials(uri2).getPassword());
-	}
-
-	@Test
-	public void testEnsureDefaultPortHttps() throws Exception {
-		URIish uri = new URIish("https://testRepo.example.com/testrepo");
-		UserPasswordCredentials credentials = new UserPasswordCredentials(
-				"agitter", "letmein");
-		store.putCredentials(uri, credentials);
-		URIish uri2 = new URIish("https://testRepo.example.com:443/testrepo");
-		assertEquals(credentials.getUser(), store.getCredentials(uri2).getUser());
-		assertEquals(credentials.getPassword(), store.getCredentials(uri2).getPassword());
-	}
-
-	@Test
-	public void testEnsureDefaultPortSftp() throws Exception {
-		URIish uri = new URIish("sftp://testRepo.example.com/testrepo");
-		UserPasswordCredentials credentials = new UserPasswordCredentials(
-				"agitter", "letmein");
-		store.putCredentials(uri, credentials);
-		URIish uri2 = new URIish("sftp://testRepo.example.com:22/testrepo");
-		assertEquals(credentials.getUser(), store.getCredentials(uri2).getUser());
-		assertEquals(credentials.getPassword(), store.getCredentials(uri2).getPassword());
-	}
-
-	@Test
-	public void testEnsureDefaultPortFtp() throws Exception {
-		URIish uri = new URIish("ftp://testRepo.example.com/testrepo");
-		UserPasswordCredentials credentials = new UserPasswordCredentials(
-				"agitter", "letmein");
-		store.putCredentials(uri, credentials);
-		URIish uri2 = new URIish("ftp://testRepo.example.com:21/testrepo");
-		assertEquals(credentials.getUser(), store.getCredentials(uri2).getUser());
-		assertEquals(credentials.getPassword(), store.getCredentials(uri2).getPassword());
-	}
-
-	@Test
-	public void testEnsureDefaultPortSsh() throws Exception {
-		URIish uri = new URIish("ssh://agitter@testRepo.example.com/testrepo");
-		UserPasswordCredentials credentials = new UserPasswordCredentials(
-				"agitter", "letmein");
-		store.putCredentials(uri, credentials);
-		URIish uri2 = new URIish("ssh://testRepo.example.com:22/testrepo");
-		assertEquals(credentials.getUser(), store.getCredentials(uri2).getUser());
-		assertEquals(credentials.getPassword(), store.getCredentials(uri2).getPassword());
-	}
-
-	@Test
-	public void testClearCredentialsTwice() throws Exception {
-		URIish uri = new URIish("http://testRepo.example.com/testrepo");
-		UserPasswordCredentials credentials = new UserPasswordCredentials(
-				"agitter", "letmein");
-		store.putCredentials(uri, credentials);
-		store.clearCredentials(uri);
-		assertEquals(null, store.getCredentials(uri));
-		store.clearCredentials(uri);
-		assertEquals(null, store.getCredentials(uri));
-	}
-
-	private void setupNewSecureStore() throws IOException,
-			MalformedURLException {
-		HashMap<String, Object> options = new HashMap<String, Object>();
-		options.put(IProviderHints.DEFAULT_PASSWORD, new PBEKeySpec(
-				"masterpass".toCharArray()));
-		String secureStorePath = ResourcesPlugin.getWorkspace().getRoot()
-				.getLocation().append("testSecureStore").toOSString();
-		File file = new File(secureStorePath);
-		if (file.exists())
-			FileUtils.delete(file, FileUtils.RECURSIVE | FileUtils.RETRY);
-		URL url = file.toURI().toURL();
-		secureStoreForTest = SecurePreferencesFactory.open(url, options);
-		secureStoreForTest.node("/GIT").removeNode();
-	}
-
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/AbstractCacheTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/AbstractCacheTest.java
deleted file mode 100644
index 11a7d88..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/AbstractCacheTest.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2011, Dariusz Luksza <dariusz@luksza.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.synchronize;
-
-import static org.eclipse.egit.core.synchronize.GitCommitsModelCache.ADDITION;
-import static org.eclipse.egit.core.synchronize.GitCommitsModelCache.CHANGE;
-import static org.eclipse.egit.core.synchronize.GitCommitsModelCache.DELETION;
-import static org.eclipse.egit.core.synchronize.GitCommitsModelCache.RIGHT;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.not;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-
-import java.util.Map;
-
-import org.eclipse.egit.core.synchronize.GitCommitsModelCache.Change;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase;
-import org.eclipse.jgit.lib.AbbreviatedObjectId;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.internal.storage.file.FileRepository;
-import org.junit.Before;
-
-@SuppressWarnings("boxing")
-public abstract class AbstractCacheTest extends LocalDiskRepositoryTestCase {
-
-	protected FileRepository db;
-
-	protected static final String INITIAL_TAG = "initial-tag";
-
-	protected static final AbbreviatedObjectId ZERO_ID = AbbreviatedObjectId.fromObjectId(ObjectId.zeroId());
-
-	@Before
-	@Override
-	// copied from org.eclipse.jgit.lib.RepositoryTestCase
-	public void setUp() throws Exception {
-		super.setUp();
-		db = createWorkRepository();
-		Git git = new Git(db);
-		git.commit().setMessage("initial commit").call();
-		git.tag().setName(INITIAL_TAG).call();
-	}
-
-	protected void assertFileAddition(Map<String, Change> result, String path, String fileName) {
-		commonFileAsserts(result, path, fileName);
-		assertThat(result.get(path).getKind(), is(RIGHT | ADDITION));
-		assertThat(result.get(path).getObjectId(), not(ZERO_ID));
-		assertNull(result.get(path).getRemoteObjectId());
-	}
-
-	protected void assertFileDeletion(Map<String, Change> result, String path, String fileName) {
-		commonFileAsserts(result, path, fileName);
-		assertThat(result.get(path).getKind(), is(RIGHT | DELETION));
-		assertThat(result.get(path).getRemoteObjectId(), not(ZERO_ID));
-		assertNull(result.get(path).getObjectId());
-	}
-
-	protected void assertFileChange(Map<String, Change> result, String path, String fileName) {
-		commonFileAsserts(result, path, fileName);
-		assertThat(result.get(path).getKind(), is(RIGHT | CHANGE));
-		assertThat(result.get(path).getObjectId(), not(ZERO_ID));
-		assertThat(result.get(path).getRemoteObjectId(), not(ZERO_ID));
-	}
-
-	private void commonFileAsserts(Map<String, Change> result, String path,
-			String fileName) {
-		assertTrue(result.containsKey(path));
-		assertThat(result.get(path).getName(), is(fileName));
-	}
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/ChangeTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/ChangeTest.java
deleted file mode 100644
index ebed329..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/ChangeTest.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2011, Dariusz Luksza <dariusz@luksza.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.synchronize;
-
-import static org.eclipse.egit.core.synchronize.GitCommitsModelCache.ZERO_ID;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import org.eclipse.egit.core.synchronize.GitCommitsModelCache.Change;
-import org.eclipse.jgit.lib.AbbreviatedObjectId;
-import org.junit.Test;
-
-public class ChangeTest {
-
-	private static final AbbreviatedObjectId MISC_ID = AbbreviatedObjectId
-			.fromString("63448b851ae8831a1ad007f588508d3246ec7ace");
-
-	@Test
-	public void shouldNotBeEqualWithNullRefference() {
-		// given
-		Change change = new Change();
-
-		// when
-		boolean result = change.equals(null);
-
-		// then
-		assertFalse(result);
-	}
-
-	@Test
-	public void shouldNotBeEqualWithDifferentType() {
-		// given
-		Change change = new Change();
-
-		// when
-		boolean result = change.equals(new Object());
-
-		// then
-		assertFalse(result);
-	}
-
-	@Test
-	public void shouldBeEqualWhenBothIdsAreNull() {
-		// given
-		Change change = new Change();
-
-		// when
-		boolean result = change.equals(new Change());
-
-		// then
-		assertTrue(result);
-	}
-
-	@Test
-	public void shouldNotBeEqualWhenOneObjectIdIsNull() {
-		// given
-		Change change = new Change();
-		change.objectId = ZERO_ID;
-
-		// when
-		boolean result = change.equals(new Change());
-
-		// then
-		assertFalse(result);
-	}
-
-	@Test
-	public void shouldBeEqualWhenBothObjectIdsAreTheSame() {
-		// given
-		Change c1 = new Change();
-		Change c2 = new Change();
-		c1.objectId = c2.objectId = MISC_ID;
-
-		// when
-		boolean result = c1.equals(c2);
-
-		// then
-		assertTrue(result);
-		assertEquals(c1.hashCode(), c2.hashCode());
-	}
-
-	@Test
-	public void shouldNotBeEqualWhenObjectIdsAreDifferent() {
-		// given
-		Change c1 = new Change();
-		Change c2 = new Change();
-		c1.objectId = ZERO_ID;
-		c2.objectId = MISC_ID;
-
-		// when
-		boolean result = c1.equals(c2);
-
-		// then
-		assertFalse(result);
-		assertFalse(c1.hashCode() == c2.hashCode());
-	}
-
-	@Test
-	public void shouldNotBeEqualWhenOneRemoteObjectIsNull() {
-		// given
-		Change c1 = new Change();
-		Change c2 = new Change();
-		c1.objectId = c2.commitId = ZERO_ID;
-		c1.remoteObjectId = MISC_ID;
-
-		// when
-		boolean result = c1.equals(c2);
-
-		// then
-		assertFalse(result);
-		assertFalse(c1.hashCode() == c2.hashCode());
-	}
-
-	@Test
-	public void shouldBeEqualWhenBothObjectIdsAndRemoteIdsAreSame() {
-		// given
-		Change c1 = new Change();
-		Change c2 = new Change();
-		c1.objectId = c2.objectId = ZERO_ID;
-		c1.remoteObjectId = c2.remoteObjectId = MISC_ID;
-
-		// when
-		boolean result = c1.equals(c2);
-
-		// then
-		assertTrue(result);
-		assertEquals(c1.hashCode(), c2.hashCode());
-	}
-
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitCommitsModelCacheTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitCommitsModelCacheTest.java
deleted file mode 100644
index 8a05e4a..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitCommitsModelCacheTest.java
+++ /dev/null
@@ -1,577 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2011, Dariusz Luksza <dariusz@luksza.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.synchronize;
-
-import static org.eclipse.egit.core.synchronize.GitCommitsModelCache.ADDITION;
-import static org.eclipse.egit.core.synchronize.GitCommitsModelCache.CHANGE;
-import static org.eclipse.egit.core.synchronize.GitCommitsModelCache.DELETION;
-import static org.eclipse.egit.core.synchronize.GitCommitsModelCache.LEFT;
-import static org.eclipse.egit.core.synchronize.GitCommitsModelCache.RIGHT;
-import static org.eclipse.jgit.junit.JGitTestUtil.deleteTrashFile;
-import static org.eclipse.jgit.junit.JGitTestUtil.writeTrashFile;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.not;
-import static org.hamcrest.CoreMatchers.notNullValue;
-import static org.hamcrest.Matchers.nullValue;
-import static org.junit.Assert.assertThat;
-
-import java.io.IOException;
-import java.util.List;
-
-import org.eclipse.egit.core.synchronize.GitCommitsModelCache.Change;
-import org.eclipse.egit.core.synchronize.GitCommitsModelCache.Commit;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.errors.AmbiguousObjectException;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.jgit.treewalk.filter.PathFilter;
-import org.junit.Test;
-
-@SuppressWarnings("boxing")
-public class GitCommitsModelCacheTest extends AbstractCacheTest {
-	@Test
-	public void shouldReturnEmptyListForSameSrcAndDstCommit() throws Exception {
-		// given
-		Git git = new Git(db);
-		RevCommit c = commit(git, "second commit");
-		// when
-		List<Commit> result = GitCommitsModelCache.build(db, c, c, null);
-		// then
-		assertThat(result, notNullValue());
-		assertThat(result.size(), is(0));
-	}
-
-	@Test
-	public void shouldNotListEmptyCommits() throws Exception {
-		// given
-		Git git = new Git(db);
-		RevCommit c = commit(git, "second commit");
-		// when
-		List<Commit> result = GitCommitsModelCache.build(db, initialTagId(), c,
-				null);
-		// then
-		assertThat(result, notNullValue());
-		assertThat(result.size(), is(0));
-	}
-
-	@Test
-	public void shouldListAdditionOrDeletionInCommit() throws Exception {
-		// given
-		Git git = new Git(db);
-		writeTrashFile(db, "a.txt", "content");
-		git.add().addFilepattern("a.txt").call();
-		RevCommit c = commit(git, "first commit");
-		// when
-		List<Commit> leftResult = GitCommitsModelCache.build(db,
-				initialTagId(), c, null);
-		List<Commit> rightResult = GitCommitsModelCache.build(db, c,
-				initialTagId(), null);
-		// then
-		// left assertions
-		assertThat(leftResult, notNullValue());
-		assertCommit(leftResult.get(0), c, 1);
-		assertFileDeletion(c, leftResult.get(0).getChildren().get("a.txt"),
-				"a.txt", LEFT);
-		// right asserts, after changing sides addition becomes deletion
-		assertThat(rightResult, notNullValue());
-		assertCommit(rightResult.get(0), c, 1);
-		assertFileAddition(c, rightResult.get(0).getChildren().get("a.txt"),
-				"a.txt", RIGHT);
-	}
-
-	@Test
-	public void shouldListAdditionOrDeletionInsideFolderInCommit()
-			throws Exception {
-		// given
-		Git git = new Git(db);
-		writeTrashFile(db, "folder/a.txt", "content");
-		git.add().addFilepattern("folder/a.txt").call();
-		RevCommit c = commit(git, "first commit");
-		// when
-		List<Commit> leftResult = GitCommitsModelCache.build(db,
-				initialTagId(), c, null);
-		List<Commit> rightResult = GitCommitsModelCache.build(db, c,
-				initialTagId(), null);
-		// then
-		// left assertions
-		assertThat(leftResult, notNullValue());
-		assertCommit(leftResult.get(0), c, 1);
-		assertThat(leftResult.get(0).getChildren().size(), is(1));
-		assertFileDeletion(c,
-				leftResult.get(0).getChildren().get("folder/a.txt"), "a.txt",
-				LEFT);
-		// right asserts, after changing sides addition becomes deletion
-		assertThat(rightResult, notNullValue());
-		assertCommit(rightResult.get(0), c, 1);
-		assertThat(rightResult.get(0).getChildren().size(), is(1));
-		assertFileAddition(c,
-				rightResult.get(0).getChildren().get("folder/a.txt"), "a.txt",
-				RIGHT);
-	}
-
-	@Test
-	public void shouldListAdditionsOrDeletionsInsideSeparateFoldersInCommit()
-			throws Exception {
-		// given
-		Git git = new Git(db);
-		writeTrashFile(db, "folder/a.txt", "content");
-		writeTrashFile(db, "folder2/b.txt", "b content");
-		git.add().addFilepattern("folder/a.txt").call();
-		git.add().addFilepattern("folder2/b.txt").call();
-		RevCommit c = commit(git, "first commit");
-		// when
-		List<Commit> leftResult = GitCommitsModelCache.build(db,
-				initialTagId(), c, null);
-		List<Commit> rightResult = GitCommitsModelCache.build(db, c,
-				initialTagId(), null);
-		// then
-		// left assertions
-		assertThat(leftResult, notNullValue());
-		assertThat(Integer.valueOf(leftResult.size()), is(Integer.valueOf(1)));
-		assertThat(leftResult.get(0).getShortMessage(), is("first commit"));
-		assertThat(leftResult.get(0).getChildren(), notNullValue());
-		assertThat(leftResult.get(0).getChildren().size(), is(2));
-		assertFileDeletion(c,
-				leftResult.get(0).getChildren().get("folder/a.txt"), "a.txt",
-				LEFT);
-		assertFileDeletion(c,
-				leftResult.get(0).getChildren().get("folder2/b.txt"), "b.txt",
-				LEFT);
-		// right asserts, after changing sides addition becomes deletion
-		assertThat(rightResult, notNullValue());
-		assertThat(Integer.valueOf(rightResult.size()), is(Integer.valueOf(1)));
-		assertThat(rightResult.get(0).getShortMessage(), is("first commit"));
-		assertThat(rightResult.get(0).getChildren(), notNullValue());
-		assertThat(rightResult.get(0).getChildren().size(), is(2));
-		assertFileAddition(c,
-				rightResult.get(0).getChildren().get("folder/a.txt"), "a.txt",
-				RIGHT);
-		assertFileAddition(c,
-				rightResult.get(0).getChildren().get("folder2/b.txt"), "b.txt",
-				RIGHT);
-	}
-
-	@Test
-	public void shouldApplyPathFilter() throws Exception {
-		// given
-		Git git = new Git(db);
-		writeTrashFile(db, "folder/a.txt", "content");
-		writeTrashFile(db, "folder2/b.txt", "b content");
-		git.add().addFilepattern("folder/a.txt").call();
-		git.add().addFilepattern("folder2/b.txt").call();
-		RevCommit c = commit(git, "first commit");
-
-		// when
-		PathFilter pathFilter = PathFilter.create("folder");
-		List<Commit> leftResult = GitCommitsModelCache.build(db,
-				initialTagId(), c, pathFilter);
-		// then
-		assertThat(leftResult, notNullValue());
-		assertThat(Integer.valueOf(leftResult.size()), is(Integer.valueOf(1)));
-		assertThat(leftResult.get(0).getShortMessage(), is("first commit"));
-		assertThat(leftResult.get(0).getChildren(), notNullValue());
-		assertThat(leftResult.get(0).getChildren().size(), is(1));
-		assertFileDeletion(c,
-				leftResult.get(0).getChildren().get("folder/a.txt"), "a.txt",
-				LEFT);
-	}
-
-	@Test
-	public void shouldListAdditionsOrDeletionsInsideFolderInCommit()
-			throws Exception {
-		// given
-		Git git = new Git(db);
-		writeTrashFile(db, "folder/a.txt", "content");
-		writeTrashFile(db, "folder/b.txt", "b content");
-		git.add().addFilepattern("folder").call();
-		RevCommit c = commit(git, "first commit");
-		// when
-		List<Commit> leftResult = GitCommitsModelCache.build(db,
-				initialTagId(), c, null);
-		List<Commit> rightResult = GitCommitsModelCache.build(db, c,
-				initialTagId(), null);
-		// then
-		// left assertions
-		assertThat(leftResult, notNullValue());
-		assertThat(Integer.valueOf(leftResult.size()), is(Integer.valueOf(1)));
-		assertCommit(leftResult.get(0), c, 2);
-		assertThat(leftResult.get(0).getChildren().size(), is(2));
-		assertFileDeletion(c,
-				leftResult.get(0).getChildren().get("folder/a.txt"), "a.txt",
-				LEFT);
-		assertFileDeletion(c,
-				leftResult.get(0).getChildren().get("folder/b.txt"), "b.txt",
-				LEFT);
-		// right asserts, after changing sides addition becomes deletion
-		assertThat(rightResult, notNullValue());
-		assertThat(Integer.valueOf(rightResult.size()), is(Integer.valueOf(1)));
-		assertCommit(rightResult.get(0), c, 2);
-		assertThat(rightResult.get(0).getChildren().size(), is(2));
-		assertFileAddition(c,
-				rightResult.get(0).getChildren().get("folder/a.txt"), "a.txt",
-				RIGHT);
-		assertFileAddition(c,
-				rightResult.get(0).getChildren().get("folder/b.txt"), "b.txt",
-				RIGHT);
-	}
-
-	@Test
-	public void shouldListChangeInCommit() throws Exception {
-		// given
-		Git git = new Git(db);
-		writeTrashFile(db, "a.txt", "content");
-		git.add().addFilepattern("a.txt").call();
-		RevCommit c1 = commit(git, "first commit");
-		writeTrashFile(db, "a.txt", "new content");
-		RevCommit c2 = commit(git, "second commit");
-		// when
-		List<Commit> leftResult = GitCommitsModelCache.build(db, c1, c2, null);
-		List<Commit> rightResult = GitCommitsModelCache.build(db, c2, c1, null);
-		// then
-		// left assertions
-		assertThat(leftResult, notNullValue());
-		assertCommit(leftResult.get(0), c2, 1);
-		assertFileChange(c1, c2, leftResult.get(0).getChildren().get("a.txt"),
-				"a.txt", LEFT);
-		// right asserts
-		assertThat(rightResult, notNullValue());
-		assertCommit(rightResult.get(0), c2, 1);
-		assertFileChange(c2, c1, rightResult.get(0).getChildren().get("a.txt"),
-				"a.txt", RIGHT);
-	}
-
-	@Test
-	public void shouldListChangeInsideFolderInCommit() throws Exception {
-		// given
-		Git git = new Git(db);
-		writeTrashFile(db, "folder/a.txt", "content");
-		git.add().addFilepattern("folder/a.txt").call();
-		RevCommit c1 = commit(git, "first commit");
-		writeTrashFile(db, "folder/a.txt", "new content");
-		RevCommit c2 = commit(git, "second commit");
-		// when
-		List<Commit> leftResult = GitCommitsModelCache.build(db, c1, c2, null);
-		List<Commit> rightResult = GitCommitsModelCache.build(db, c2, c1, null);
-		// then
-		// left assertions
-		assertThat(leftResult, notNullValue());
-		assertCommit(leftResult.get(0), c2, 1);
-		assertFileChange(c1, c2,
-				leftResult.get(0).getChildren().get("folder/a.txt"), "a.txt",
-				LEFT);
-		// right asserts
-		assertThat(rightResult, notNullValue());
-		assertCommit(rightResult.get(0), c2, 1);
-		assertFileChange(c2, c1,
-				rightResult.get(0).getChildren().get("folder/a.txt"), "a.txt",
-				RIGHT);
-	}
-
-	@Test
-	public void shouldListChangesInsideSeparateFoldersInCommit()
-			throws Exception {
-		// given
-		Git git = new Git(db);
-		writeTrashFile(db, "folder/a.txt", "content");
-		writeTrashFile(db, "folder2/b.txt", "b content");
-		git.add().addFilepattern("folder/a.txt").call();
-		git.add().addFilepattern("folder2/b.txt").call();
-		RevCommit c1 = commit(git, "first commit");
-		writeTrashFile(db, "folder/a.txt", "new content");
-		writeTrashFile(db, "folder2/b.txt", "new b content");
-		RevCommit c2 = commit(git, "second commit");
-		// when
-		List<Commit> leftResult = GitCommitsModelCache.build(db, c1, c2, null);
-		List<Commit> rightResult = GitCommitsModelCache.build(db, c2, c1, null);
-		// then
-		// left assertions
-		assertThat(leftResult, notNullValue());
-		assertThat(Integer.valueOf(leftResult.size()), is(Integer.valueOf(1)));
-		assertThat(leftResult.get(0).getShortMessage(), is("second commit"));
-		assertThat(leftResult.get(0).getChildren(), notNullValue());
-		assertThat(leftResult.get(0).getChildren().size(), is(2));
-		assertFileChange(c1, c2,
-				leftResult.get(0).getChildren().get("folder/a.txt"), "a.txt",
-				LEFT);
-		assertFileChange(c1, c2,
-				leftResult.get(0).getChildren().get("folder2/b.txt"), "b.txt",
-				LEFT);
-		// right asserts
-		assertThat(rightResult, notNullValue());
-		assertThat(Integer.valueOf(rightResult.size()), is(Integer.valueOf(1)));
-		assertThat(rightResult.get(0).getShortMessage(), is("second commit"));
-		assertThat(rightResult.get(0).getChildren().size(), is(2));
-		assertFileChange(c2, c1,
-				rightResult.get(0).getChildren().get("folder/a.txt"), "a.txt",
-				RIGHT);
-		assertFileChange(c2, c1,
-				rightResult.get(0).getChildren().get("folder2/b.txt"), "b.txt",
-				RIGHT);
-	}
-
-	@Test
-	public void shouldListChangesInsideFolderInCommit() throws Exception {
-		// given
-		Git git = new Git(db);
-		writeTrashFile(db, "folder/a.txt", "content");
-		writeTrashFile(db, "folder/b.txt", "b content");
-		git.add().addFilepattern("folder").call();
-		RevCommit c1 = commit(git, "first commit");
-		writeTrashFile(db, "folder/a.txt", "new content");
-		writeTrashFile(db, "folder/b.txt", "new b content");
-		RevCommit c2 = commit(git, "second commit");
-		// when
-		List<Commit> leftResult = GitCommitsModelCache.build(db, c1, c2, null);
-		List<Commit> rightResult = GitCommitsModelCache.build(db, c2, c1, null);
-		// then
-		// left assertions
-		assertThat(leftResult, notNullValue());
-		assertThat(Integer.valueOf(leftResult.size()), is(Integer.valueOf(1)));
-		assertCommit(leftResult.get(0), c2, 2);
-		assertFileChange(c1, c2,
-				leftResult.get(0).getChildren().get("folder/a.txt"), "a.txt",
-				LEFT);
-		assertFileChange(c1, c2,
-				leftResult.get(0).getChildren().get("folder/b.txt"), "b.txt",
-				LEFT);
-		// right asserts
-		assertThat(rightResult, notNullValue());
-		assertThat(Integer.valueOf(rightResult.size()), is(Integer.valueOf(1)));
-		assertCommit(rightResult.get(0), c2, 2);
-		assertFileChange(c2, c1,
-				rightResult.get(0).getChildren().get("folder/a.txt"), "a.txt",
-				RIGHT);
-		assertFileChange(c2, c1,
-				rightResult.get(0).getChildren().get("folder/b.txt"), "b.txt",
-				RIGHT);
-	}
-
-	@Test
-	public void shouldListAllTypeOfChangesInOneCommit() throws Exception {
-		// given
-		Git git = new Git(db);
-		writeTrashFile(db, "a.txt", "a content");
-		writeTrashFile(db, "c.txt", "c content");
-		git.add().addFilepattern("a.txt").call();
-		git.add().addFilepattern("c.txt").call();
-		RevCommit c1 = commit(git, "first commit");
-		deleteTrashFile(db, "a.txt");
-		writeTrashFile(db, "b.txt", "b content");
-		writeTrashFile(db, "c.txt", "new c content");
-		git.add().addFilepattern("b.txt").call();
-		RevCommit c2 = commit(git, "second commit");
-		// when
-		List<Commit> leftResult = GitCommitsModelCache.build(db, c1, c2, null);
-		List<Commit> rightResult = GitCommitsModelCache.build(db, c2, c1, null);
-		// then
-		// left asserts
-		assertThat(leftResult, notNullValue());
-		assertCommit(leftResult.get(0), c2, 3);
-		assertFileAddition(c1, c2,
-				leftResult.get(0).getChildren().get("a.txt"), "a.txt", LEFT);
-		assertFileDeletion(c1, c2,
-				leftResult.get(0).getChildren().get("b.txt"), "b.txt", LEFT);
-		assertFileChange(c1, c2, leftResult.get(0).getChildren().get("c.txt"),
-				"c.txt", LEFT);
-		// right asserts
-		assertThat(rightResult, notNullValue());
-		assertCommit(rightResult.get(0), c2, 3);
-		assertFileDeletion(c2, c1, rightResult.get(0).getChildren()
-				.get("a.txt"), "a.txt", RIGHT);
-		assertFileAddition(c2, c1, rightResult.get(0).getChildren()
-				.get("b.txt"), "b.txt", RIGHT);
-		assertFileChange(c2, c1, rightResult.get(0).getChildren().get("c.txt"),
-				"c.txt", RIGHT);
-	}
-
-	@Test
-	public void shouldListAllTypeOfChangesInsideFolderInOneCommit()
-			throws Exception {
-		// given
-		Git git = new Git(db);
-		writeTrashFile(db, "folder/a.txt", "a content");
-		writeTrashFile(db, "folder/c.txt", "c content");
-		git.add().addFilepattern("folder/a.txt").call();
-		git.add().addFilepattern("folder/c.txt").call();
-		RevCommit c1 = commit(git, "first commit");
-		deleteTrashFile(db, "folder/a.txt");
-		writeTrashFile(db, "folder/b.txt", "b content");
-		writeTrashFile(db, "folder/c.txt", "new c content");
-		git.add().addFilepattern("folder/b.txt").call();
-		RevCommit c2 = commit(git, "second commit");
-		// when
-		List<Commit> leftResult = GitCommitsModelCache.build(db, c1, c2, null);
-		List<Commit> rightResult = GitCommitsModelCache.build(db, c2, c1, null);
-		// then
-		// left assertions
-		assertThat(leftResult, notNullValue());
-		assertCommit(leftResult.get(0), c2, 3);
-		assertFileAddition(c1, c2,
-				leftResult.get(0).getChildren().get("folder/a.txt"), "a.txt",
-				LEFT);
-		assertFileDeletion(c1, c2,
-				leftResult.get(0).getChildren().get("folder/b.txt"), "b.txt",
-				LEFT);
-		assertFileChange(c1, c2,
-				leftResult.get(0).getChildren().get("folder/c.txt"), "c.txt",
-				LEFT);
-		// right asserts
-		assertThat(rightResult, notNullValue());
-		assertCommit(rightResult.get(0), c2, 3);
-		assertFileDeletion(c2, c1,
-				rightResult.get(0).getChildren().get("folder/a.txt"), "a.txt",
-				RIGHT);
-		assertFileAddition(c2, c1,
-				rightResult.get(0).getChildren().get("folder/b.txt"), "b.txt",
-				RIGHT);
-		assertFileChange(c2, c1,
-				rightResult.get(0).getChildren().get("folder/c.txt"), "c.txt",
-				RIGHT);
-	}
-
-	@Test
-	public void shouldListAllTypeOfChangesInsideSeparateFoldersInOneCommit()
-			throws Exception {
-		// given
-		Git git = new Git(db);
-		writeTrashFile(db, "folder/a.txt", "a content");
-		writeTrashFile(db, "folder2/c.txt", "c content");
-		git.add().addFilepattern("folder/a.txt").call();
-		git.add().addFilepattern("folder2/c.txt").call();
-		RevCommit c1 = commit(git, "first commit");
-		deleteTrashFile(db, "folder/a.txt");
-		writeTrashFile(db, "folder1/b.txt", "b content");
-		writeTrashFile(db, "folder2/c.txt", "new c content");
-		git.add().addFilepattern("folder1/b.txt").call();
-		RevCommit c2 = commit(git, "second commit");
-		// when
-		List<Commit> leftResult = GitCommitsModelCache.build(db, c1, c2, null);
-		List<Commit> rightResult = GitCommitsModelCache.build(db, c2, c1, null);
-		// then
-		// left assertions
-		assertThat(leftResult, notNullValue());
-		assertThat(Integer.valueOf(leftResult.size()), is(Integer.valueOf(1)));
-		assertThat(leftResult.get(0).getShortMessage(), is("second commit"));
-		assertThat(leftResult.get(0).getChildren(), notNullValue());
-		assertThat(leftResult.get(0).getChildren().size(), is(3));
-		assertFileAddition(c1, c2,
-				leftResult.get(0).getChildren().get("folder/a.txt"), "a.txt",
-				LEFT);
-		assertFileDeletion(c1, c2,
-				leftResult.get(0).getChildren().get("folder1/b.txt"), "b.txt",
-				LEFT);
-		assertFileChange(c1, c2,
-				leftResult.get(0).getChildren().get("folder2/c.txt"), "c.txt",
-				LEFT);
-		// right asserts
-		assertThat(rightResult, notNullValue());
-		assertThat(Integer.valueOf(rightResult.size()), is(Integer.valueOf(1)));
-		assertThat(rightResult.get(0).getShortMessage(), is("second commit"));
-		assertThat(rightResult.get(0).getChildren(), notNullValue());
-		assertThat(rightResult.get(0).getChildren().size(), is(3));
-		assertFileDeletion(c2, c1,
-				rightResult.get(0).getChildren().get("folder/a.txt"), "a.txt",
-				RIGHT);
-		assertFileAddition(c2, c1,
-				rightResult.get(0).getChildren().get("folder1/b.txt"), "b.txt",
-				RIGHT);
-		assertFileChange(c2, c1,
-				rightResult.get(0).getChildren().get("folder2/c.txt"), "c.txt",
-				RIGHT);
-	}
-
-	private RevCommit commit(Git git, String msg) throws Exception {
-		tick();
-		return git.commit().setAll(true).setMessage(msg)
-				.setCommitter(committer).call();
-	}
-
-	private ObjectId initialTagId() throws AmbiguousObjectException,
-			IOException {
-		return db.resolve(INITIAL_TAG);
-	}
-
-	private void assertCommit(Commit commit, RevCommit actualCommit,
-			int childrenCount) {
-		commonCommitAsserts(commit, actualCommit);
-		assertThat(commit.getChildren(), notNullValue());
-		assertThat(commit.getChildren().size(), is(childrenCount));
-	}
-
-	private void commonCommitAsserts(Commit commit, RevCommit actualCommit) {
-		assertThat(commit.getShortMessage(), is(actualCommit.getShortMessage()));
-		assertThat(commit.getId().toObjectId(), is(actualCommit.getId()));
-		assertThat(commit.getAuthorName(), is(actualCommit.getAuthorIdent()
-				.getName()));
-		assertThat(commit.getCommitterName(), is(actualCommit
-				.getCommitterIdent().getName()));
-		assertThat(commit.getCommitDate(), is(actualCommit.getAuthorIdent()
-				.getWhen()));
-	}
-
-	private void assertFileChange(RevCommit actual, RevCommit parent,
-			Change change, String name, int direction) {
-		commonFileAssertions(actual, parent, change, name);
-		assertThat(change.getObjectId(), not(ZERO_ID));
-		assertThat(change.getRemoteObjectId(), not(ZERO_ID));
-		if (direction == LEFT)
-			assertThat(change.getKind(), is(LEFT | CHANGE));
-		else
-			assertThat(change.getKind(), is(RIGHT | CHANGE));
-	}
-
-	private void assertFileAddition(RevCommit actual, Change change,
-			String name, int direction) {
-		assertFileAddition(actual, null, change, name, direction);
-	}
-
-	private void assertFileAddition(RevCommit actual, RevCommit parent,
-			Change change, String name, int direction) {
-		commonFileAssertions(actual, parent, change, name);
-		if (direction == LEFT) {
-			assertThat(change.getKind(), is(LEFT | ADDITION));
-			assertThat(change.getRemoteCommitId(), not(ZERO_ID));
-			assertThat(change.getObjectId(), nullValue());
-		} else { // should be Differencer.Right
-			assertThat(change.getKind(), is(RIGHT | ADDITION));
-			assertThat(change.getObjectId(), not(ZERO_ID));
-			assertThat(change.getRemoteObjectId(), nullValue());
-		}
-	}
-
-	private void assertFileDeletion(RevCommit parent, Change change,
-			String name, int direction) {
-		assertFileDeletion(null, parent, change, name, direction);
-	}
-
-	private void assertFileDeletion(RevCommit actual, RevCommit parent,
-			Change change, String name, int direction) {
-		commonFileAssertions(actual, parent, change, name);
-		if (direction == LEFT) {
-			assertThat(change.getRemoteObjectId(), nullValue());
-			assertThat(change.getObjectId(), not(ZERO_ID));
-			assertThat(change.getKind(), is(LEFT | DELETION));
-		} else { // should be Differencer.Right
-			assertThat(change.getKind(), is(RIGHT | DELETION));
-			assertThat(change.getObjectId(), nullValue());
-			assertThat(change.getRemoteObjectId(), not(ZERO_ID));
-		}
-	}
-
-	private void commonFileAssertions(RevCommit actual, RevCommit parent,
-			Change change, String name) {
-		assertThat(change, notNullValue());
-		if (parent != null)
-			assertThat(change.getRemoteCommitId().toObjectId(),
-					is(parent.getId()));
-		if (actual != null && !ObjectId.zeroId().equals(actual))
-			assertThat(change.getCommitId().toObjectId(), is(actual.getId()));
-		assertThat(change.getName(), is(name));
-	}
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitResourceVariantComparatorTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitResourceVariantComparatorTest.java
deleted file mode 100644
index 621f6c1..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitResourceVariantComparatorTest.java
+++ /dev/null
@@ -1,694 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.synchronize;
-
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-import static org.eclipse.jgit.lib.Constants.HEAD;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.util.Arrays;
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IStorage;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
-import org.eclipse.egit.core.test.GitTestCase;
-import org.eclipse.egit.core.test.TestRepository;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.jgit.treewalk.TreeWalk;
-import org.eclipse.team.core.variants.IResourceVariant;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class GitResourceVariantComparatorTest extends GitTestCase {
-
-	private Repository repo;
-
-	private IProject iProject;
-
-	private TestRepository testRepo;
-
-	@Before
-	public void setUp() throws Exception {
-		super.setUp();
-
-		iProject = project.project;
-		testRepo = new TestRepository(gitDir);
-		testRepo.connect(iProject);
-		repo = RepositoryMapping.getMapping(iProject).getRepository();
-
-		// make initial commit
-		new Git(repo).commit().setAuthor("JUnit", "junit@jgit.org")
-				.setMessage("Initall commit").call();
-	}
-
-	@After
-	public void clearGitResources() throws Exception {
-		testRepo.disconnect(iProject);
-		testRepo.dispose();
-		repo = null;
-		super.tearDown();
-	}
-
-	/* ============================================
-	 * compare(IResource, IResourceVariant) tests
-	 * ============================================ */
-
-	/**
-	 * When remote variant wasn't found, compare method is called with null as
-	 * second parameter. In this case compare should return false.
-	 */
-	@Test
-	@SuppressWarnings("boxing")
-	public void shouldReturnFalseWhenRemoteDoesNotExist() {
-		// when
-		GitResourceVariantComparator grvc = new GitResourceVariantComparator(
-				null);
-
-		// given
-		IResource local = mock(IResource.class);
-		when(local.exists()).thenReturn(false);
-
-		// then
-		assertFalse(grvc.compare(local, null));
-	}
-
-	@Test
-	@SuppressWarnings("boxing")
-	public void shouldReturnFalseWhenRemoteDoesNotExist2() throws Exception {
-		// when
-		GitResourceVariantComparator grvc = new GitResourceVariantComparator(
-				null);
-
-		// given
-		IResource local = mock(IResource.class);
-		when(local.exists()).thenReturn(false);
-		IResourceVariant remote = new GitRemoteFolder(repo, null, null, null, "./");
-
-		// then
-		assertFalse(grvc.compare(local, remote));
-	}
-
-	/**
-	 * It is possible to have a local file that has same name as a remote
-	 * folder. In some cases that two resources can be compared. In this case
-	 * compare method should return false, because they aren't same resources
-	 */
-	@Test
-	@SuppressWarnings("boxing")
-	public void shouldReturnFalseWhenComparingFileAndContainer() {
-		// when
-		GitResourceVariantComparator grvc = new GitResourceVariantComparator(
-				null);
-
-		// given
-		IFile local = mock(IFile.class);
-		when(local.exists()).thenReturn(true);
-
-		IResourceVariant remote = mock(IResourceVariant.class);
-		when(remote.isContainer()).thenReturn(true);
-
-		// then
-		assertFalse(grvc.compare(local, remote));
-	}
-
-	/**
-	 * Comparing two folders that have different path should return false.
-	 *
-	 * @throws Exception
-	 */
-	@Test
-	@SuppressWarnings("boxing")
-	public void shouldReturnFalseWhenComparingContainerAndContainer()
-			throws Exception {
-		// when
-		GitResourceVariantComparator grvc = new GitResourceVariantComparator(
-				null);
-
-		// given
-		IPath localPath = mock(IPath.class);
-		IContainer local = mock(IContainer.class);
-		when(local.exists()).thenReturn(true);
-		when(local.getLocation()).thenReturn(localPath);
-
-		File file = testRepo.createFile(iProject, "test" + File.separator
-				+ "keep");
-		RevCommit commit = testRepo.addAndCommit(iProject, file,
-				"initial commit");
-		String path = Repository.stripWorkDir(repo.getWorkTree(), file);
-
-		GitRemoteFolder remote = new GitRemoteFolder(repo, null, commit,
-				commit.getTree(), path);
-
-		// then
-		assertFalse(grvc.compare(local, remote));
-	}
-
-	/**
-	 * When comparing two folders that have same path, compare() method should
-	 * return true.
-	 *
-	 * @throws Exception
-	 */
-	@Test
-	@SuppressWarnings("boxing")
-	public void shouldReturnTrueWhenComparingContainerAndContainer()
-			throws Exception {
-		// when
-		GitResourceVariantComparator grvc = new GitResourceVariantComparator(
-				null);
-
-		// given
-		File file = testRepo.createFile(iProject, "test" + File.separator
-				+ "keep");
-		RevCommit commit = testRepo.addAndCommit(iProject, file,
-				"initial commit");
-		String path = Repository.stripWorkDir(repo.getWorkTree(), file);
-		IPath iPath = new Path(path);
-
-		IContainer local = mock(IContainer.class);
-		when(local.exists()).thenReturn(true);
-		when(local.getLocation()).thenReturn(iPath);
-
-		GitRemoteFolder remote = new GitRemoteFolder(repo, null, commit,
-				commit.getTree(), path);
-
-		// then
-		assertTrue(grvc.compare(local, remote));
-	}
-
-	/**
-	 * Compare() should return false when comparing two files with different
-	 * content length
-	 *
-	 * @throws Exception
-	 */
-	@Test
-	@SuppressWarnings("boxing")
-	public void shouldReturnFalseWhenContentLengthIsDifferent()
-			throws Exception {
-		// when
-		byte[] shortContent = "short content".getBytes();
-		byte[] longContent = "very long long content".getBytes();
-		GitSynchronizeData data = new GitSynchronizeData(repo, HEAD, HEAD, true);
-		GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data);
-		GitResourceVariantComparator grvc = new GitResourceVariantComparator(
-				dataSet);
-
-		// given
-		IFile local = mock(IFile.class);
-		when(local.exists()).thenReturn(true);
-		when(local.getProject()).thenReturn(project.getProject());
-		when(local.getContents()).thenReturn(
-				new ByteArrayInputStream(longContent));
-
-		IStorage storage = mock(IStorage.class);
-		when(storage.getContents()).thenReturn(
-				new ByteArrayInputStream(shortContent));
-
-		IResourceVariant remote = mock(IResourceVariant.class);
-		when(remote.isContainer()).thenReturn(false);
-		when(remote.getStorage(any(IProgressMonitor.class))).thenReturn(
-				storage);
-
-		// then
-		assertFalse(grvc.compare(local, remote));
-	}
-
-	/**
-	 * Comparing two files that have same content length but having small
-	 * difference inside content should return false.
-	 *
-	 * @throws Exception
-	 */
-	@Test
-	@SuppressWarnings("boxing")
-	public void shouldReturnFalseWhenShortContentIsDifferent() throws Exception {
-		// when
-		byte[] localContent = "very long long content".getBytes();
-		// this typo should be here
-		byte[] remoteContent = "very long lonk content".getBytes();
-		GitSynchronizeData data = new GitSynchronizeData(repo, HEAD, HEAD, true);
-		GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data);
-		GitResourceVariantComparator grvc = new GitResourceVariantComparator(
-				dataSet);
-
-		// given
-		IFile local = mock(IFile.class);
-		when(local.exists()).thenReturn(true);
-		when(local.getProject()).thenReturn(project.getProject());
-		when(local.getContents()).thenReturn(
-				new ByteArrayInputStream(localContent));
-
-		IStorage storage = mock(IStorage.class);
-		when(storage.getContents()).thenReturn(
-				new ByteArrayInputStream(remoteContent));
-
-		IResourceVariant remote = mock(IResourceVariant.class);
-		when(remote.isContainer()).thenReturn(false);
-		when(remote.getStorage(any(IProgressMonitor.class))).thenReturn(
-				storage);
-
-		// then
-		assertFalse(grvc.compare(local, remote));
-	}
-
-	/**
-	 * Comparing two 'large' files that have same length and almost identical
-	 * content should return false.
-	 *
-	 * @throws Exception
-	 */
-	@Test
-	@SuppressWarnings("boxing")
-	public void shouldReturnFalseWhenLongContentIsDifferent() throws Exception {
-		// when
-		byte[] localContent = new byte[8192];
-		Arrays.fill(localContent, (byte) 'a');
-		byte[] remoteContent = new byte[8192];
-		Arrays.fill(remoteContent, (byte) 'a');
-		remoteContent[8101] = 'b';
-		GitSynchronizeData data = new GitSynchronizeData(repo, HEAD, HEAD, true);
-		GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data);
-		GitResourceVariantComparator grvc = new GitResourceVariantComparator(
-				dataSet);
-
-		// given
-		IFile local = mock(IFile.class);
-		when(local.exists()).thenReturn(true);
-		when(local.getProject()).thenReturn(project.getProject());
-		when(local.getContents()).thenReturn(
-				new ByteArrayInputStream(localContent));
-
-		IStorage storage = mock(IStorage.class);
-		when(storage.getContents()).thenReturn(
-				new ByteArrayInputStream(remoteContent));
-
-		IResourceVariant remote = mock(IResourceVariant.class);
-		when(remote.isContainer()).thenReturn(false);
-		when(remote.getStorage(any(IProgressMonitor.class))).thenReturn(
-				storage);
-
-		// then
-		assertFalse(grvc.compare(local, remote));
-	}
-
-	/**
-	 * Comparing two 'large' files that have different length but same content
-	 * should return false.
-	 * <p>
-	 * This and previous three test cases cover almost the same functionality
-	 * but they are covering all return points in compare methods that can be
-	 * used when comparing files content
-	 *
-	 * @throws Exception
-	 */
-	@Test
-	@SuppressWarnings("boxing")
-	public void shouldReturnFalseWhenLongContentLengthIsDifferent()
-			throws Exception {
-		// when
-		byte[] localContent = new byte[8192];
-		Arrays.fill(localContent, (byte) 'a');
-		byte[] remoteContent = new byte[8200];
-		Arrays.fill(remoteContent, (byte) 'a');
-		GitSynchronizeData data = new GitSynchronizeData(repo, HEAD, HEAD, true);
-		GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data);
-		GitResourceVariantComparator grvc = new GitResourceVariantComparator(
-				dataSet);
-
-		// given
-		IFile local = mock(IFile.class);
-		when(local.exists()).thenReturn(true);
-		when(local.getProject()).thenReturn(project.getProject());
-		when(local.getContents()).thenReturn(
-				new ByteArrayInputStream(localContent));
-
-		IStorage storage = mock(IStorage.class);
-		when(storage.getContents()).thenReturn(
-				new ByteArrayInputStream(remoteContent));
-
-		IResourceVariant remote = mock(IResourceVariant.class);
-		when(remote.isContainer()).thenReturn(false);
-		when(remote.getStorage(any(IProgressMonitor.class))).thenReturn(
-				storage);
-
-		// then
-		assertFalse(grvc.compare(local, remote));
-	}
-
-	/**
-	 * Comparing two files that have the same content and content length should
-	 * return true
-	 *
-	 * @throws Exception
-	 */
-	@Test
-	@SuppressWarnings("boxing")
-	public void shouldReturnTrueWhenShortContentIsDifferent() throws Exception {
-		// when
-		byte[] localContent = "very long long content".getBytes();
-		byte[] remoteContent = "very long long content".getBytes();
-		GitSynchronizeData data = new GitSynchronizeData(repo, HEAD, HEAD, true);
-		GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data);
-		GitResourceVariantComparator grvc = new GitResourceVariantComparator(
-				dataSet);
-
-		// given
-		IFile local = mock(IFile.class);
-		when(local.exists()).thenReturn(true);
-		when(local.getProject()).thenReturn(project.getProject());
-		when(local.getContents()).thenReturn(
-				new ByteArrayInputStream(localContent));
-
-		IStorage storage = mock(IStorage.class);
-		when(storage.getContents()).thenReturn(
-				new ByteArrayInputStream(remoteContent));
-
-		IResourceVariant remote = mock(IResourceVariant.class);
-		when(remote.isContainer()).thenReturn(false);
-		when(remote.getStorage(any(IProgressMonitor.class))).thenReturn(
-				storage);
-
-		// then
-		assertTrue(grvc.compare(local, remote));
-	}
-
-	/**
-	 * Compare two 'large' files that have same content length and content
-	 * should return true.
-	 *
-	 * @throws Exception
-	 */
-	@Test
-	@SuppressWarnings("boxing")
-	public void shouldReturnTrueWhenLongContentLengthIsDifferent()
-			throws Exception {
-		// when
-		byte[] localContent = new byte[8192];
-		Arrays.fill(localContent, (byte) 'a');
-		byte[] remoteContent = new byte[8192];
-		Arrays.fill(remoteContent, (byte) 'a');
-		GitSynchronizeData data = new GitSynchronizeData(repo, HEAD, HEAD, true);
-		GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data);
-		GitResourceVariantComparator grvc = new GitResourceVariantComparator(
-				dataSet);
-
-		// given
-		IFile local = mock(IFile.class);
-		when(local.exists()).thenReturn(true);
-		when(local.getProject()).thenReturn(project.getProject());
-		when(local.getContents()).thenReturn(
-				new ByteArrayInputStream(localContent));
-
-		IStorage storage = mock(IStorage.class);
-		when(storage.getContents()).thenReturn(
-				new ByteArrayInputStream(remoteContent));
-
-		IResourceVariant remote = mock(IResourceVariant.class);
-		when(remote.isContainer()).thenReturn(false);
-		when(remote.getStorage(any(IProgressMonitor.class))).thenReturn(
-				storage);
-
-		// then
-		assertTrue(grvc.compare(local, remote));
-	}
-
-	/* ==================================================
-	 * compare(IResourceVariant, IResourceVariant) tests
-	 * ================================================== */
-
-	/**
-	 * When comparing file that don't exist in base, but exists in remote
-	 * compare method should return false.
-	 *
-	 * @throws Exception
-	 */
-	@Test
-	public void shouldReturnFalseWhenBaseDoesntExist() throws Exception {
-		// when
-		GitResourceVariantComparator grvc = new GitResourceVariantComparator(
-				null);
-
-		// given
-		RevCommit baseCommit = testRepo.createInitialCommit("initial commit");
-		testRepo.createAndCheckoutBranch(Constants.HEAD, Constants.R_HEADS
-				+ "test");
-		File file = testRepo.createFile(iProject, "test-file");
-		RevCommit remoteCommit = testRepo.addAndCommit(iProject, file,
-				"second commit");
-		String path = Repository.stripWorkDir(repo.getWorkTree(), file);
-
-		GitRemoteFile base = new GitRemoteFile(repo, baseCommit,
-				baseCommit.getTree(), path);
-		GitRemoteFile remote = new GitRemoteFile(repo, baseCommit,
-				remoteCommit.getTree(), path);
-
-		// then
-		assertFalse(grvc.compare(base, remote));
-	}
-
-	/**
-	 * Compare() should return false when remote file does not exists, but
-	 * equivalent local file exist.
-	 *
-	 * @throws Exception
-	 */
-	@Test
-	public void shouldReturnFalseWhenRemoteVariantDoesntExist()
-			throws Exception {
-		// when
-		GitResourceVariantComparator grvc = new GitResourceVariantComparator(
-				null);
-
-		// given
-		RevCommit remoteCommit = testRepo.createInitialCommit("initial commit");
-		testRepo.createAndCheckoutBranch(Constants.HEAD, Constants.R_HEADS
-				+ "test");
-		File file = testRepo.createFile(iProject, "test-file");
-		RevCommit baseCommit = testRepo.addAndCommit(iProject, file,
-				"second commit");
-		String path = Repository.stripWorkDir(repo.getWorkTree(), file);
-
-		GitRemoteFile base = new GitRemoteFile(repo, baseCommit,
-				baseCommit.getTree(), path);
-		GitRemoteFile remote = new GitRemoteFile(repo, remoteCommit,
-				remoteCommit.getTree(), path);
-
-		// then
-		assertFalse(grvc.compare(base, remote));
-	}
-
-	/**
-	 * Return false when comparing incompatible types (file against folder) that
-	 * also maps onto different resources
-	 *
-	 * @throws Exception
-	 */
-	@Test
-	public void shouldReturnFalseWhenComparingRemoteVariantFileWithContainer()
-			throws Exception {
-		// when
-		GitResourceVariantComparator grvc = new GitResourceVariantComparator(
-				null);
-
-		// given
-		File file = testRepo.createFile(iProject, "test" + File.separator
-				+ "keep");
-		RevCommit commit = testRepo.addAndCommit(iProject, file,
-				"initial commit");
-		String filePath = Repository.stripWorkDir(repo.getWorkTree(), file);
-		String folderPath = Repository.stripWorkDir(repo.getWorkTree(),
-				new File(file.getParent()));
-		GitRemoteFile base = new GitRemoteFile(repo, commit, commit.getTree(),
-				filePath);
-		GitRemoteFolder remote = new GitRemoteFolder(repo, null, commit,
-				commit.getTree(), folderPath);
-
-		// then
-		assertFalse(grvc.compare(base, remote));
-	}
-
-	/**
-	 * Return false when comparing incompatible types (folder against file) that
-	 * also map onto different resources
-	 *
-	 * @throws Exception
-	 */
-	@Test
-	public void shouldReturnFalseWhenComparingRemoteVariantContainerWithFile()
-			throws Exception {
-		// when
-		GitResourceVariantComparator grvc = new GitResourceVariantComparator(
-				null);
-
-		// given
-		File file = testRepo.createFile(iProject, "test" + File.separator
-				+ "keep");
-		RevCommit commit = testRepo.addAndCommit(iProject, file,
-				"initial commit");
-		String filePath = Repository.stripWorkDir(repo.getWorkTree(), file);
-		String folderPath = Repository.stripWorkDir(repo.getWorkTree(),
-				new File(file.getParent()));
-
-		GitRemoteFolder base = new GitRemoteFolder(repo, null, commit,
-				commit.getTree(), folderPath);
-		GitRemoteFile remote = new GitRemoteFile(repo, commit,
-				commit.getTree(), filePath);
-
-		// then
-		assertFalse(grvc.compare(base, remote));
-	}
-
-	/**
-	 * When comparing two remote variants that have different path compare
-	 * method should return false
-	 *
-	 * @throws Exception
-	 */
-	@Test
-	public void shouldReturnFalseWhenComparingRemoteVariantContainerWithContainer()
-			throws Exception {
-		// when
-		GitResourceVariantComparator grvc = new GitResourceVariantComparator(
-				null);
-
-		// given
-		File file1 = testRepo.createFile(iProject, "test1" + File.separator
-				+ "keep1");
-		File file2 = testRepo.createFile(iProject, "test2" + File.separator
-				+ "keep2");
-		testRepo.track(file1);
-		testRepo.track(file2);
-		testRepo.addToIndex(testRepo.getIFile(iProject, file1));
-		testRepo.addToIndex(testRepo.getIFile(iProject, file2));
-		RevCommit commit = testRepo.commit("initial commit");
-
-		TreeWalk tw = new TreeWalk(repo);
-		int nth = tw.addTree(commit.getTree());
-
-		tw.next();
-		tw.enterSubtree(); // enter project node
-		tw.next();
-		GitRemoteFolder base = new GitRemoteFolder(repo, null, commit,
-				tw.getObjectId(nth), tw.getNameString());
-
-		tw.next();
-		GitRemoteFolder remote = new GitRemoteFolder(repo, null, commit,
-				tw.getObjectId(nth), tw.getNameString());
-
-		// then
-		assertFalse(grvc.compare(base, remote));
-	}
-
-	/**
-	 * Comparing two remote folders that have same path should return true
-	 *
-	 * @throws Exception
-	 */
-	@Test
-	public void shouldReturnTrueWhenComparingRemoteVariantContainerWithContainer()
-			throws Exception {
-		// when
-		GitResourceVariantComparator grvc = new GitResourceVariantComparator(
-				null);
-
-		// given
-		File file1 = testRepo.createFile(iProject, "test1" + File.separator
-				+ "keep1");
-		testRepo.track(file1);
-		testRepo.addToIndex(testRepo.getIFile(iProject, file1));
-		RevCommit commit = testRepo.commit("initial commit");
-
-		String path1 = Repository.stripWorkDir(repo.getWorkTree(), new File(
-				file1.getParent()));
-
-		GitRemoteFolder base = new GitRemoteFolder(repo, null, commit,
-				commit.getTree(), path1);
-		GitRemoteFolder remote = new GitRemoteFolder(repo, null, commit,
-				commit.getTree(), path1);
-
-		// then
-		assertTrue(grvc.compare(base, remote));
-	}
-
-	/**
-	 * Comparing two remote files that have different git ObjectId should return false.
-	 *
-	 * @throws Exception
-	 */
-	@Test
-	public void shouldReturnFalseWhenComparingRemoteVariantWithDifferentObjectId()
-			throws Exception {
-		// when
-		GitResourceVariantComparator grvc = new GitResourceVariantComparator(
-				null);
-
-		// given
-		File file = testRepo.createFile(iProject, "test-file");
-		RevCommit baseCommit = testRepo.appendContentAndCommit(iProject, file,
-				"a", "initial commit");
-		RevCommit remoteCommit = testRepo.appendContentAndCommit(iProject,
-				file, "bc", "second commit");
-
-		String path = Repository.stripWorkDir(repo.getWorkTree(), file);
-		GitRemoteFile base = new GitRemoteFile(repo, baseCommit,
-				baseCommit.getTree(), path);
-
-		GitRemoteFile remote = new GitRemoteFile(repo, remoteCommit,
-				remoteCommit.getTree(), path);
-
-		// then
-		assertFalse(grvc.compare(base, remote));
-	}
-
-	/**
-	 * Comparing two remote files that have the same git ObjectId should return
-	 * true.
-	 *
-	 * @throws Exception
-	 */
-	@Test
-	public void shouldReturnTrueWhenComparingRemoteVariant() throws Exception {
-		// when
-		GitResourceVariantComparator grvc = new GitResourceVariantComparator(
-				null);
-
-		// given
-		File file = testRepo.createFile(iProject, "test-file");
-		RevCommit commit = testRepo.appendContentAndCommit(iProject, file,
-				"a", "initial commit");
-
-		String path = Repository.stripWorkDir(repo.getWorkTree(), file);
-		GitRemoteFile base = new GitRemoteFile(repo, commit, commit.getTree(),
-				path);
-
-		GitRemoteFile remote = new GitRemoteFile(repo, commit,
-				commit.getTree(), path);
-
-		// then
-		assertTrue(grvc.compare(base, remote));
-	}
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitResourceVariantTreeSubscriberTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitResourceVariantTreeSubscriberTest.java
deleted file mode 100755
index 17c9f59..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitResourceVariantTreeSubscriberTest.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2010, 2012 Dariusz Luksza <dariusz@luksza.org> and others.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.synchronize;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.io.File;
-import java.io.IOException;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
-import org.eclipse.egit.core.test.GitTestCase;
-import org.eclipse.egit.core.test.TestRepository;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.jgit.treewalk.TreeWalk;
-import org.eclipse.jgit.treewalk.filter.PathFilter;
-import org.eclipse.team.core.TeamException;
-import org.eclipse.team.core.variants.IResourceVariant;
-import org.eclipse.team.core.variants.IResourceVariantTree;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-
-public class GitResourceVariantTreeSubscriberTest extends GitTestCase {
-
-	private Repository repo;
-
-	private IProject iProject;
-
-	private TestRepository testRepo;
-
-	@Before
-	public void setUp() throws Exception {
-		super.setUp();
-		iProject = project.getProject();
-		testRepo = new TestRepository(gitDir);
-		testRepo.connect(iProject);
-		repo = RepositoryMapping.getMapping(iProject).getRepository();
-	}
-
-	@After
-	public void clearGitResources() throws Exception {
-		testRepo.disconnect(iProject);
-		testRepo.dispose();
-		repo = null;
-		super.tearDown();
-	}
-
-	/**
-	 * This test simulates that user work and made some changes on branch 'test'
-	 * and then try to synchronize "test" and 'master' branch.
-	 *
-	 * @throws Exception
-	 */
-	@Test
-	public void shouldReturnSrcBranchAsBase() throws Exception {
-		// when
-		String fileName = "Main.java";
-		File file = testRepo.createFile(iProject, fileName);
-		RevCommit commit = testRepo.appendContentAndCommit(iProject, file,
-				"class Main {}", "initial commit");
-		IFile mainJava = testRepo.getIFile(iProject, file);
-		testRepo.createAndCheckoutBranch(Constants.HEAD, Constants.R_HEADS
-				+ "test");
-		testRepo.appendContentAndCommit(iProject, file, "// test1",
-				"secont commit");
-
-		// given
-		GitResourceVariantTreeSubscriber grvts = createGitResourceVariantTreeSubscriber(
-				Constants.HEAD, Constants.R_HEADS + Constants.MASTER);
-		grvts.init(new NullProgressMonitor());
-		IResourceVariantTree baseTree = grvts.getBaseTree();
-
-		// then
-		IResourceVariant actual = commonAssertionsForBaseTree(baseTree,
-				mainJava);
-		assertEquals(commit.abbreviate(7).name() + "... (J. Git)",
-				actual.getContentIdentifier());
-	}
-
-	/**
-	 * Both source and destination branches has some different commits but they
-	 * has also common ancestor. This situation is described more detailed in
-	 * bug #317934
-	 *
-	 * This test passes when it is run as a stand alone test case, but it fails
-	 * when it is run as part of test suite. It throws NPE when it try's to
-	 * checkout master branch.
-	 *
-	 * @throws Exception
-	 */
-	@Test
-	@Ignore
-	public void shouldReturnCommonAncestorAsBase() throws Exception {
-		// when
-		String fileName = "Main.java";
-		File file = testRepo.createFile(iProject, fileName);
-		RevCommit commit = testRepo.appendContentAndCommit(iProject, file,
-				"class Main {}", "initial commit");
-		IFile mainJava = testRepo.getIFile(iProject, file);
-		// this should be our common ancestor
-		ObjectId fileId = findFileId(commit, mainJava);
-
-		testRepo.createAndCheckoutBranch(Constants.HEAD, Constants.R_HEADS
-				+ "test");
-		testRepo.appendContentAndCommit(iProject, file, "// test 1",
-				"second commit");
-
-		testRepo.checkoutBranch(Constants.R_HEADS + Constants.MASTER);
-		testRepo.appendContentAndCommit(iProject, file, "// test 2",
-				"third commit");
-
-		// given
-		GitResourceVariantTreeSubscriber grvts = createGitResourceVariantTreeSubscriber(
-				Constants.HEAD, Constants.R_HEADS + "test");
-		grvts.getBaseTree();
-		IResourceVariantTree baseTree = grvts.getBaseTree();
-
-		// then
-		IResourceVariant actual = commonAssertionsForBaseTree(baseTree,
-				mainJava);
-		assertEquals(fileId.getName(), actual.getContentIdentifier());
-	}
-
-	/**
-	 * This test passes when it is run as a stand alone test case, but it fails
-	 * when it is run as part of test suite. It throws NPE when it try's to
-	 * checkout master branch.
-	 *
-	 * @throws Exception
-	 */
-	@Test
-	@Ignore
-	public void shouldReturnRemoteTree() throws Exception {
-		// when
-		String fileName = "Main.java";
-		File file = testRepo.createFile(iProject, fileName);
-		testRepo.appendContentAndCommit(iProject, file,
-				"class Main {}", "initial commit");
-		IFile mainJava = testRepo.getIFile(iProject, file);
-
-		testRepo.createAndCheckoutBranch(Constants.HEAD, Constants.R_HEADS
-				+ "test");
-		RevCommit commit = testRepo.appendContentAndCommit(iProject, file, "// test 1",
-				"second commit");
-		ObjectId fileId = findFileId(commit, mainJava);
-
-		// given
-		GitResourceVariantTreeSubscriber grvts = createGitResourceVariantTreeSubscriber(
-				Constants.HEAD, "test");
-		grvts.getBaseTree();
-		IResourceVariantTree remoteTree = grvts.getRemoteTree();
-
-		// then
-		assertNotNull(remoteTree);
-		assertTrue(remoteTree instanceof GitRemoteResourceVariantTree);
-		IResourceVariant resourceVariant = remoteTree
-				.getResourceVariant(mainJava);
-		assertNotNull(resourceVariant);
-		assertTrue(resourceVariant instanceof GitRemoteResource);
-		assertEquals(fileId.getName(), resourceVariant.getContentIdentifier());
-	}
-
-	private GitResourceVariantTreeSubscriber createGitResourceVariantTreeSubscriber(
-			String src, String dst) throws IOException {
-		GitSynchronizeData gsd = new GitSynchronizeData(repo, src, dst, false);
-		GitSynchronizeDataSet gsds = new GitSynchronizeDataSet(gsd);
-		new GitResourceVariantTreeSubscriber(gsds);
-		return new GitResourceVariantTreeSubscriber(gsds);
-	}
-
-	private ObjectId findFileId(RevCommit commit, IFile mainJava)
-			throws Exception {
-		TreeWalk tw = new TreeWalk(repo);
-		tw.reset();
-		tw.setRecursive(true);
-		String path = Repository.stripWorkDir(repo.getWorkTree(), mainJava
-				.getLocation().toFile());
-		tw.setFilter(PathFilter.create(path));
-		int nth = tw.addTree(commit.getTree());
-		tw.next();
-
-		return tw.getObjectId(nth);
-	}
-
-	private IResourceVariant commonAssertionsForBaseTree(
-			IResourceVariantTree baseTree, IResource resource)
-			throws TeamException {
-		assertNotNull(baseTree);
-		assertTrue(baseTree instanceof GitBaseResourceVariantTree);
-		IResourceVariant resourceVariant = baseTree
-				.getResourceVariant(resource);
-		assertNotNull(resourceVariant);
-		assertTrue(resourceVariant instanceof GitRemoteResource);
-		return resourceVariant;
-	}
-
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitResourceVariantTreeTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitResourceVariantTreeTest.java
deleted file mode 100644
index d8f656a..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitResourceVariantTreeTest.java
+++ /dev/null
@@ -1,278 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.synchronize;
-
-import static org.eclipse.jgit.lib.Constants.HEAD;
-import static org.eclipse.jgit.lib.Constants.MASTER;
-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 java.io.File;
-import java.io.InputStream;
-import java.util.Arrays;
-import java.util.Comparator;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.egit.core.op.ConnectProviderOperation;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
-import org.eclipse.egit.core.test.GitTestCase;
-import org.eclipse.egit.core.test.TestProject;
-import org.eclipse.egit.core.test.TestRepository;
-import org.eclipse.jdt.core.IPackageFragment;
-import org.eclipse.jdt.core.IType;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.team.core.variants.IResourceVariant;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class GitResourceVariantTreeTest extends GitTestCase {
-
-	private Repository repo;
-
-	private IProject iProject;
-
-	private TestRepository testRepo;
-
-	@Before
-	public void createGitRepository() throws Exception {
-		iProject = project.project;
-		testRepo = new TestRepository(gitDir);
-		testRepo.connect(iProject);
-		repo = RepositoryMapping.getMapping(iProject).getRepository();
-	}
-
-	@After
-	public void clearGitResources() throws Exception {
-		testRepo.disconnect(iProject);
-		testRepo.dispose();
-		repo = null;
-		super.tearDown();
-	}
-
-	/**
-	 * roots() method should return list of projects that are associated with
-	 * given repository. In this case there is only one project associated with
-	 * this repository therefore only one root should be returned.
-	 *
-	 * @throws Exception
-	 */
-	@Test
-	public void shouldReturnOneRoot() throws Exception {
-		// when
-		new Git(repo).commit().setAuthor("JUnit", "junit@egit.org")
-				.setMessage("Initial commit").call();
-		GitSynchronizeData data = new GitSynchronizeData(repo, HEAD, HEAD,
-				false);
-		GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data);
-
-		// given
-		GitResourceVariantTree grvt = new GitTestResourceVariantTree(dataSet,
-				null, null);
-
-		// then
-		assertEquals(1, grvt.roots().length);
-		IResource actualProject = grvt.roots()[0];
-		assertEquals(this.project.getProject(), actualProject);
-	}
-
-	/**
-	 * When we have two or more project associated with repository, roots()
-	 * method should return list of project. In this case we have two project
-	 * associated with particular repository, therefore '2' value is expected.
-	 *
-	 * @throws Exception
-	 */
-	@Test
-	public void shouldReturnTwoRoots() throws Exception {
-		// when
-		// create second project
-		TestProject secondProject = new TestProject(true, "Project-2");
-		try {
-			IProject secondIProject = secondProject.project;
-			// add connect project with repository
-			new ConnectProviderOperation(secondIProject, gitDir).execute(null);
-			new Git(repo).commit().setAuthor("JUnit", "junit@egit.org")
-					.setMessage("Initial commit").call();
-			GitSynchronizeData data = new GitSynchronizeData(repo, HEAD, HEAD,
-					false);
-			GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data);
-
-			// given
-			GitResourceVariantTree grvt = new GitTestResourceVariantTree(dataSet,
-					null, null);
-
-			// then
-			IResource[] roots = grvt.roots();
-			// sort in order to be able to assert the project instances
-			Arrays.sort(roots, new Comparator<IResource>() {
-				public int compare(IResource r1, IResource r2) {
-					String path1 = r1.getFullPath().toString();
-					String path2 = r2.getFullPath().toString();
-					return path1.compareTo(path2);
-				}
-			});
-			assertEquals(2, roots.length);
-			IResource actualProject = roots[0];
-			assertEquals(this.project.project, actualProject);
-			IResource actualProject1 = roots[1];
-			assertEquals(secondIProject, actualProject1);
-		} finally {
-			secondProject.dispose();
-		}
-	}
-
-	/**
-	 * Checks that getResourceVariant will not throw NPE for null argument. This
-	 * method is called with null argument when local or remote resource does
-	 * not exist.
-	 *
-	 * @throws Exception
-	 */
-	@Test
-	public void shouldReturnNullResourceVariant() throws Exception {
-		// when
-		new Git(repo).commit().setAuthor("JUnit", "junit@egit.org")
-				.setMessage("Initial commit").call();
-		GitSynchronizeData data = new GitSynchronizeData(repo, HEAD, MASTER,
-				false);
-		GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data);
-
-		// given
-		GitResourceVariantTree grvt = new GitRemoteResourceVariantTree(null,
-				dataSet);
-
-		// then
-		assertNull(grvt.getResourceVariant(null));
-	}
-
-	/**
-	 * getResourceVariant() should return null when given resource doesn't exist
-	 * in repository.
-	 *
-	 * @throws Exception
-	 */
-	@Test
-	public void shouldReturnNullResourceVariant2() throws Exception {
-		// when
-		IPackageFragment iPackage = project.createPackage("org.egit.test");
-		IType mainJava = project.createType(iPackage, "Main.java",
-				"class Main {}");
-		new Git(repo).commit().setAuthor("JUnit", "junit@egit.org")
-				.setMessage("Initial commit").call();
-		GitSynchronizeData data = new GitSynchronizeData(repo, HEAD, MASTER,
-				false);
-		GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data);
-		GitSyncCache cache = GitSyncCache.getAllData(dataSet,
-				new NullProgressMonitor());
-
-		// given
-		GitResourceVariantTree grvt = new GitRemoteResourceVariantTree(cache,
-				dataSet);
-
-		// then
-		assertNull(grvt.getResourceVariant(mainJava.getResource()));
-	}
-
-	/**
-	 * Check if getResourceVariant() does return the same resource that was
-	 * committed. Passes only when it is run as a single test, not as a part of
-	 * largest test suite
-	 *
-	 * @throws Exception
-	 */
-	@Test
-	public void shoulReturnSameResourceVariant() throws Exception {
-		// when
-		String fileName = "Main.java";
-		File file = testRepo.createFile(iProject, fileName);
-		testRepo.appendContentAndCommit(iProject, file, "class Main {}",
-				"initial commit");
-		IFile mainJava = testRepo.getIFile(iProject, file);
-		GitSynchronizeData data = new GitSynchronizeData(repo, HEAD, MASTER,
-				false);
-		GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data);
-		GitSyncCache cache = GitSyncCache.getAllData(dataSet,
-				new NullProgressMonitor());
-
-		// given
-		GitResourceVariantTree grvt = new GitRemoteResourceVariantTree(cache,
-				dataSet);
-
-		// then
-		// null variant indicates that resource wasn't changed
-		assertNull(grvt.getResourceVariant(mainJava));
-	}
-
-	/**
-	 * Create and commit Main.java file in master branch, then create branch
-	 * "test" checkout nearly created branch and modify Main.java file.
-	 * getResourceVariant() should obtain Main.java file content from "master"
-	 * branch. Passes only when it is run as a single test, not as a part of
-	 * largest test suite
-	 *
-	 * @throws Exception
-	 */
-	@Test
-	public void shouldReturnDifferentResourceVariant() throws Exception {
-		// when
-		String fileName = "Main.java";
-		File file = testRepo.createFile(iProject, fileName);
-		testRepo.appendContentAndCommit(iProject, file, "class Main {}",
-				"initial commit");
-		IFile mainJava = testRepo.getIFile(iProject, file);
-
-		testRepo.createAndCheckoutBranch(Constants.R_HEADS + Constants.MASTER,
-				Constants.R_HEADS + "test");
-		testRepo.appendContentAndCommit(iProject, file, "// test",
-				"first commit");
-		GitSynchronizeData data = new GitSynchronizeData(repo, HEAD, MASTER,
-				true);
-		GitSynchronizeDataSet dataSet = new GitSynchronizeDataSet(data);
-		GitSyncCache cache = GitSyncCache.getAllData(dataSet,
-				new NullProgressMonitor());
-
-		// given
-		GitResourceVariantTree grvt = new GitBaseResourceVariantTree(cache,
-				dataSet);
-
-		// then
-		IResourceVariant actual = grvt.getResourceVariant(mainJava);
-		assertNotNull(actual);
-		assertEquals(fileName, actual.getName());
-
-		InputStream actualIn = actual.getStorage(new NullProgressMonitor())
-				.getContents();
-		byte[] actualByte = getBytesAndCloseStream(actualIn);
-		InputStream expectedIn = mainJava.getContents();
-		byte[] expectedByte = getBytesAndCloseStream(expectedIn);
-
-		// assert arrays not equals
-		assertFalse(Arrays.equals(expectedByte, actualByte));
-	}
-
-	private byte[] getBytesAndCloseStream(InputStream stream) throws Exception {
-		try {
-			byte[] actualByte = new byte[stream.available()];
-			stream.read(actualByte);
-			return actualByte;
-		} finally {
-			stream.close();
-		}
-	}
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitSubscriberMergeContextTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitSubscriberMergeContextTest.java
deleted file mode 100644
index 833061b..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitSubscriberMergeContextTest.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2011, 2012 Benjamin Muskalla <benjamin.muskalla@tasktop.com>
- * and others.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.synchronize;
-
-import static junit.framework.Assert.assertTrue;
-import static org.eclipse.jgit.lib.Constants.HEAD;
-import static org.junit.Assert.assertEquals;
-
-import java.io.File;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.mapping.ResourceMapping;
-import org.eclipse.egit.core.AdapterUtils;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
-import org.eclipse.egit.core.test.GitTestCase;
-import org.eclipse.egit.core.test.TestRepository;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.api.Status;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.team.core.diff.IDiff;
-import org.eclipse.team.core.mapping.provider.ResourceDiff;
-import org.eclipse.team.core.subscribers.SubscriberScopeManager;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class GitSubscriberMergeContextTest extends GitTestCase {
-
-	private Repository repo;
-
-	private IProject iProject;
-
-	private TestRepository testRepo;
-
-	@Before
-	public void setUp() throws Exception {
-		super.setUp();
-
-		iProject = project.project;
-		testRepo = new TestRepository(gitDir);
-		testRepo.connect(iProject);
-		repo = RepositoryMapping.getMapping(iProject).getRepository();
-
-		// make initial commit
-		new Git(repo).commit().setAuthor("JUnit", "junit@jgit.org")
-				.setMessage("Initial commit").call();
-	}
-
-	@After
-	public void clearGitResources() throws Exception {
-		testRepo.disconnect(iProject);
-		testRepo.dispose();
-		repo = null;
-		super.tearDown();
-	}
-
-	@Test
-	public void markAsMerged() throws Exception {
-		GitSynchronizeData gsd = new GitSynchronizeData(repo, HEAD, HEAD, false);
-		GitSynchronizeDataSet gsds = new GitSynchronizeDataSet(gsd);
-		GitResourceVariantTreeSubscriber subscriber = new GitResourceVariantTreeSubscriber(
-				gsds);
-
-		String fileName = "src/Main.java";
-		File file = testRepo.createFile(iProject, fileName);
-		testRepo.appendContentAndCommit(iProject, file, "class Main {}",
-				"some file");
-		testRepo.addToIndex(iProject.getFile(".classpath"));
-		testRepo.addToIndex(iProject.getFile(".project"));
-		testRepo.commit("project files");
-
-		IFile workspaceFile = testRepo.getIFile(iProject, file);
-
-		ResourceMapping mapping = AdapterUtils.adapt(workspaceFile, ResourceMapping.class);
-		ResourceMapping[] inputMappings = new ResourceMapping[] { mapping };
-		SubscriberScopeManager manager = new SubscriberScopeManager("Scope",
-				inputMappings, subscriber, true);
-
-		testRepo.appendFileContent(file, "some changes");
-		Status status = new Git(repo).status().call();
-		assertEquals(0, status.getAdded().size());
-		assertEquals(1, status.getModified().size());
-		String repoRelativePath = testRepo.getRepoRelativePath(workspaceFile.getLocation().toPortableString());
-		assertTrue(status.getModified().contains(repoRelativePath));
-
-		GitSubscriberMergeContext mergeContext = new GitSubscriberMergeContext(
-				subscriber, manager, gsds);
-		IDiff node = new ResourceDiff(iProject.getFolder("src"), IDiff.CHANGE);
-		mergeContext.markAsMerged(node, true, null);
-
-		status = new Git(repo).status().call();
-		assertEquals(1, status.getChanged().size());
-		assertEquals(0, status.getModified().size());
-		assertTrue(status.getChanged().contains(repoRelativePath));
-
-	}
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitTestResourceVariantTree.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitTestResourceVariantTree.java
deleted file mode 100644
index 52369bb..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/GitTestResourceVariantTree.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.synchronize;
-
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.team.core.variants.ResourceVariantByteStore;
-
-/**
- * Implementation of abstract {@link GitResourceVariantTree} class. It is only
- * used in {@link GitResourceVariantTreeTest} for testing public methods that
- * are implemented in base class.
- */
-class GitTestResourceVariantTree extends GitResourceVariantTree {
-
-	GitTestResourceVariantTree(GitSynchronizeDataSet data,
-			GitSyncCache cache, ResourceVariantByteStore store) {
-		super(store, cache, data);
-	}
-
-	@Override
-	protected ObjectId getObjectId(ThreeWayDiffEntry diffEntry) {
-		return null;
-	}
-
-	@Override
-	protected RevCommit getCommitId(GitSynchronizeData gsd) {
-		return null;
-	}
-
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/StagedChangeCacheTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/StagedChangeCacheTest.java
deleted file mode 100644
index cfbc3e8..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/StagedChangeCacheTest.java
+++ /dev/null
@@ -1,235 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2011, Dariusz Luksza <dariusz@luksza.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.synchronize;
-
-import static org.eclipse.jgit.junit.JGitTestUtil.writeTrashFile;
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertThat;
-
-import java.util.Map;
-
-import org.eclipse.egit.core.synchronize.GitCommitsModelCache.Change;
-import org.eclipse.jgit.api.Git;
-import org.junit.Test;
-
-@SuppressWarnings("boxing")
-public class StagedChangeCacheTest extends AbstractCacheTest {
-
-	@Test
-	public void shouldListSingleWorkspaceAddition() throws Exception {
-		// given
-		writeTrashFile(db, "a.txt", "trash");
-		new Git(db).add().addFilepattern("a.txt").call();
-
-		// when
-		Map<String, Change> result = StagedChangeCache.build(db);
-
-		// then
-		assertThat(result.size(), is(1));
-		assertFileAddition(result, "a.txt", "a.txt");
-	}
-
-	@Test
-	public void shouldListTwoWorkspaceAdditions() throws Exception {
-		// given
-		writeTrashFile(db, "a.txt", "trash");
-		writeTrashFile(db, "b.txt", "trash");
-		new Git(db).add().addFilepattern("a.txt").addFilepattern("b.txt").call();
-
-		// when
-		Map<String, Change> result = StagedChangeCache.build(db);
-
-		// then
-		assertThat(result.size(), is(2));
-		assertFileAddition(result, "a.txt", "a.txt");
-		assertFileAddition(result, "b.txt", "b.txt");
-	}
-
-	@Test
-	public void shouldListSingleWorkspaceAdditionInFolder() throws Exception {
-		// given
-		writeTrashFile(db, "folder/a.txt", "trash");
-		new Git(db).add().addFilepattern("folder/a.txt").call();
-
-		// when
-		Map<String, Change> result = StagedChangeCache.build(db);
-
-		// then
-		assertThat(result.size(), is(1));
-		assertFileAddition(result, "folder/a.txt", "a.txt");
-	}
-
-	@Test
-	public void shouldListTwoWorkspaceAdditionsInFolder() throws Exception {
-		// given
-		writeTrashFile(db, "folder/a.txt", "trash");
-		writeTrashFile(db, "folder/b.txt", "trash");
-		new Git(db).add().addFilepattern("folder/a.txt").addFilepattern("folder/b.txt").call();
-
-		// when
-		Map<String, Change> result = StagedChangeCache.build(db);
-
-		// then
-		assertThat(result.size(), is(2));
-		assertFileAddition(result, "folder/a.txt", "a.txt");
-		assertFileAddition(result, "folder/b.txt", "b.txt");
-	}
-
-	@Test
-	public void shouldListSingleWorkspaceDeletion() throws Exception {
-		// given
-		Git git = new Git(db);
-		writeTrashFile(db, "a.txt", "trash");
-		git.add().addFilepattern("a.txt").call();
-		git.commit().setMessage("initial add").call();
-		git.rm().addFilepattern("a.txt").call();
-
-		// when
-		Map<String, Change> result = StagedChangeCache.build(db);
-
-		// then
-		assertThat(result.size(), is(1));
-		assertFileDeletion(result, "a.txt", "a.txt");
-	}
-
-	@Test
-	public void shouldListTwoWorkspaceDeletions() throws Exception {
-		// given
-		Git git = new Git(db);
-		writeTrashFile(db, "a.txt", "trash");
-		writeTrashFile(db, "b.txt", "trash");
-		git.add().addFilepattern("a.txt").addFilepattern("b.txt").call();
-		git.commit().setMessage("new commit").call();
-		git.rm().addFilepattern("a.txt").addFilepattern("b.txt").call();
-
-		// when
-		Map<String, Change> result = StagedChangeCache.build(db);
-
-		// then
-		assertThat(result.size(), is(2));
-		assertFileDeletion(result, "a.txt", "a.txt");
-		assertFileDeletion(result, "b.txt", "b.txt");
-	}
-
-	@Test
-	public void shouldListSingleWorkspaceDeletionInFolder() throws Exception {
-		// given
-		Git git = new Git(db);
-		writeTrashFile(db, "folder/a.txt", "trash");
-		git.add().addFilepattern("folder/a.txt").call();
-		git.commit().setMessage("new commit").call();
-		git.rm().addFilepattern("folder/a.txt").call();
-
-		// when
-		Map<String, Change> result = StagedChangeCache.build(db);
-
-		// then
-		assertThat(result.size(), is(1));
-		assertFileDeletion(result, "folder/a.txt", "a.txt");
-	}
-
-	@Test
-	public void shouldListTwoWorkspaceDeletionsInFolder() throws Exception {
-		// given
-		Git git = new Git(db);
-		writeTrashFile(db, "folder/a.txt", "trash");
-		writeTrashFile(db, "folder/b.txt", "trash");
-		git.add().addFilepattern("folder/a.txt").addFilepattern("folder/b.txt").call();
-		git.commit().setMessage("new commit").call();
-		git.rm().addFilepattern("folder/a.txt").call();
-		git.rm().addFilepattern("folder/b.txt").call();
-
-		// when
-		Map<String, Change> result = StagedChangeCache.build(db);
-
-		// then
-		assertThat(result.size(), is(2));
-		assertFileDeletion(result, "folder/a.txt", "a.txt");
-		assertFileDeletion(result, "folder/b.txt", "b.txt");
-	}
-
-	@Test
-	public void shouldListSingleWorkspaceChange() throws Exception {
-		// given
-		Git git = new Git(db);
-		writeTrashFile(db, "a.txt", "trash");
-		git.add().addFilepattern("a.txt").call();
-		git.commit().setMessage("initial a.txt commit").call();
-		writeTrashFile(db, "a.txt", "modification");
-		git.add().addFilepattern("a.txt").call();
-
-		// when
-		Map<String, Change> result = StagedChangeCache.build(db);
-
-		// then
-		assertThat(result.size(), is(1));
-		assertFileChange(result, "a.txt", "a.txt");
-	}
-
-	@Test
-	public void shouldListTwoWorkspaceChanges() throws Exception {
-		// given
-		Git git = new Git(db);
-		writeTrashFile(db, "a.txt", "trash");
-		writeTrashFile(db, "b.txt", "trash");
-		git.add().addFilepattern("a.txt").addFilepattern("b.txt").call();
-		git.commit().setMessage("new commmit").call();
-		writeTrashFile(db, "a.txt", "modification");
-		writeTrashFile(db, "b.txt", "modification");
-		git.add().addFilepattern("a.txt").addFilepattern("b.txt").call();
-
-		// when
-		Map<String, Change> result = StagedChangeCache.build(db);
-
-		// then
-		assertThat(result.size(), is(2));
-		assertFileChange(result, "a.txt", "a.txt");
-		assertFileChange(result, "b.txt", "b.txt");
-	}
-
-	@Test
-	public void shouldListSingleWorkspaceChangeInFolder() throws Exception {
-		// given
-		Git git = new Git(db);
-		writeTrashFile(db, "folder/a.txt", "trash");
-		git.add().addFilepattern("folder/a.txt").call();
-		git.commit().setMessage("new commit").call();
-		writeTrashFile(db, "folder/a.txt", "modification");
-		git.add().addFilepattern("folder/a.txt").call();
-
-		// when
-		Map<String, Change> result = StagedChangeCache.build(db);
-
-		// then
-		assertThat(result.size(), is(1));
-		assertFileChange(result, "folder/a.txt", "a.txt");
-	}
-
-	@Test
-	public void shouldListTwoWorkspaceChagneInFolder() throws Exception {
-		// given
-		Git git = new Git(db);
-		writeTrashFile(db, "folder/a.txt", "trash");
-		writeTrashFile(db, "folder/b.txt", "trash");
-		git.add().addFilepattern("folder/a.txt").addFilepattern("folder/b.txt").call();
-		git.commit().setMessage("new commit").call();
-		writeTrashFile(db, "folder/a.txt", "modification");
-		writeTrashFile(db, "folder/b.txt", "modification");
-		git.add().addFilepattern("folder/a.txt").addFilepattern("folder/b.txt").call();
-
-		// when
-		Map<String, Change> result = StagedChangeCache.build(db);
-
-		// then
-		assertThat(result.size(), is(2));
-		assertFileChange(result, "folder/a.txt", "a.txt");
-		assertFileChange(result, "folder/b.txt", "b.txt");
-	}
-
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/ThreeWayDiffEntryTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/ThreeWayDiffEntryTest.java
deleted file mode 100644
index 1e6bb95..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/ThreeWayDiffEntryTest.java
+++ /dev/null
@@ -1,285 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2011, Dariusz Luksza <dariusz@luksza.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.synchronize;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.notNullValue;
-import static org.junit.Assert.assertThat;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.List;
-
-import org.eclipse.egit.core.synchronize.ThreeWayDiffEntry.ChangeType;
-import org.eclipse.egit.core.synchronize.ThreeWayDiffEntry.Direction;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase;
-import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.jgit.internal.storage.file.FileRepository;
-import org.eclipse.jgit.treewalk.EmptyTreeIterator;
-import org.eclipse.jgit.treewalk.TreeWalk;
-import org.junit.Before;
-import org.junit.Test;
-
-public class ThreeWayDiffEntryTest extends LocalDiskRepositoryTestCase {
-
-	private FileRepository db;
-
-	@Before
-	@Override
-	// copied from org.eclipse.jgit.lib.RepositoryTestCase
-	public void setUp() throws Exception {
-		super.setUp();
-		db = createWorkRepository();
-	}
-
-	@Test
-	public void shouldListOutgoingAddition() throws Exception {
-		// given
-		writeTrashFile("a.txt", "content");
-		Git git = new Git(db);
-		git.add().addFilepattern("a.txt").call();
-		RevCommit c = git.commit().setMessage("initial commit").call();
-
-		// when
-		TreeWalk walk = new TreeWalk(db);
-		walk.addTree(c.getTree());
-		walk.addTree(new EmptyTreeIterator());
-		walk.addTree(new EmptyTreeIterator());
-		List<ThreeWayDiffEntry> result = ThreeWayDiffEntry.scan(walk);
-
-		// then
-		assertThat(result, notNullValue());
-		assertThat(Integer.valueOf(result.size()), is(Integer.valueOf(1)));
-
-		ThreeWayDiffEntry entry = result.get(0);
-		assertThat(entry.getDirection(), is(Direction.OUTGOING));
-		assertThat(entry.getChangeType(), is(ChangeType.ADD));
-		assertThat(entry.getPath(), is("a.txt"));
-	}
-
-	@Test
-	public void shouldListIncomingAddition() throws Exception {
-		// given
-		writeTrashFile("a.txt", "content");
-		Git git = new Git(db);
-		git.add().addFilepattern("a.txt").call();
-		RevCommit c = git.commit().setMessage("initial commit").call();
-
-		// when
-		TreeWalk walk = new TreeWalk(db);
-		walk.addTree(new EmptyTreeIterator());
-		walk.addTree(new EmptyTreeIterator());
-		walk.addTree(c.getTree());
-		List<ThreeWayDiffEntry> result = ThreeWayDiffEntry.scan(walk);
-
-		// then
-		assertThat(result, notNullValue());
-		assertThat(Integer.valueOf(result.size()), is(Integer.valueOf(1)));
-
-		ThreeWayDiffEntry entry = result.get(0);
-		assertThat(entry.getDirection(), is(Direction.INCOMING));
-		assertThat(entry.getChangeType(), is(ChangeType.ADD));
-		assertThat(entry.getPath(), is("a.txt"));
-	}
-
-	@Test
-	public void shouldListOutgoingDelete() throws Exception {
-		// given
-		writeTrashFile("a.txt", "content");
-		Git git = new Git(db);
-		git.add().addFilepattern("a.txt").call();
-		RevCommit c = git.commit().setMessage("initial commit").call();
-
-		// when
-		TreeWalk walk = new TreeWalk(db);
-		walk.addTree(new EmptyTreeIterator());
-		walk.addTree(c.getTree());
-		walk.addTree(c.getTree());
-		List<ThreeWayDiffEntry> result = ThreeWayDiffEntry.scan(walk);
-
-		// then
-		assertThat(result, notNullValue());
-		assertThat(Integer.valueOf(result.size()), is(Integer.valueOf(1)));
-
-		ThreeWayDiffEntry entry = result.get(0);
-		assertThat(entry.getDirection(), is(Direction.OUTGOING));
-		assertThat(entry.getChangeType(), is(ChangeType.DELETE));
-		assertThat(entry.getPath(), is("a.txt"));
-	}
-
-	@Test
-	public void shouldListIncomingDelete() throws Exception {
-		// given
-		writeTrashFile("a.txt", "content");
-		Git git = new Git(db);
-		git.add().addFilepattern("a.txt").call();
-		RevCommit c = git.commit().setMessage("initial commit").call();
-
-		// when
-		TreeWalk walk = new TreeWalk(db);
-		walk.addTree(c.getTree());
-		walk.addTree(c.getTree());
-		walk.addTree(new EmptyTreeIterator());
-		List<ThreeWayDiffEntry> result = ThreeWayDiffEntry.scan(walk);
-
-		// then
-		assertThat(result, notNullValue());
-		assertThat(Integer.valueOf(result.size()), is(Integer.valueOf(1)));
-
-		ThreeWayDiffEntry entry = result.get(0);
-		assertThat(entry.getDirection(), is(Direction.INCOMING));
-		assertThat(entry.getChangeType(), is(ChangeType.DELETE));
-		assertThat(entry.getPath(), is("a.txt"));
-	}
-
-	@Test
-	public void shouldListConflictingChange() throws Exception {
-		// given
-		writeTrashFile("a.txt", "content");
-		Git git = new Git(db);
-		git.add().addFilepattern("a.txt").call();
-		RevCommit c = git.commit().setMessage("initial commit").call();
-
-		// when
-		TreeWalk walk = new TreeWalk(db);
-		walk.addTree(new EmptyTreeIterator());
-		walk.addTree(c.getTree());
-		walk.addTree(new EmptyTreeIterator());
-		List<ThreeWayDiffEntry> result = ThreeWayDiffEntry.scan(walk);
-
-		// then
-		assertThat(result, notNullValue());
-		assertThat(Integer.valueOf(result.size()), is(Integer.valueOf(1)));
-
-		ThreeWayDiffEntry entry = result.get(0);
-		assertThat(entry.getDirection(), is(Direction.CONFLICTING));
-		assertThat(entry.getChangeType(), is(ChangeType.MODIFY));
-		// assertThat(entry.getNewPath(), is("a.txt"));
-		// assertThat(entry.getOldPath(), is(DEV_NULL));
-	}
-
-	@Test
-	public void shouldListConflictingChange2() throws Exception {
-		// given
-		writeTrashFile("a.txt", "content");
-		Git git = new Git(db);
-		git.add().addFilepattern("a.txt").call();
-		RevCommit c = git.commit().setMessage("initial commit").call();
-
-		// when
-		TreeWalk walk = new TreeWalk(db);
-		walk.addTree(c.getTree());
-		walk.addTree(new EmptyTreeIterator());
-		walk.addTree(c.getTree());
-		List<ThreeWayDiffEntry> result = ThreeWayDiffEntry.scan(walk);
-
-		// then
-		assertThat(result, notNullValue());
-		assertThat(Integer.valueOf(result.size()), is(Integer.valueOf(1)));
-
-		ThreeWayDiffEntry entry = result.get(0);
-		assertThat(entry.getDirection(), is(Direction.CONFLICTING));
-		assertThat(entry.getChangeType(), is(ChangeType.MODIFY));
-		assertThat(entry.getPath(), is("a.txt"));
-	}
-
-	@Test
-	public void shouldListIncomingModify() throws Exception {
-		// given
-		writeTrashFile("a.txt", "content");
-		Git git = new Git(db);
-		git.add().addFilepattern("a.txt").call();
-		RevCommit c = git.commit().setMessage("initial commit").call();
-		writeTrashFile("a.txt", "new line");
-		RevCommit c1 = git.commit().setAll(true).setMessage("second commit")
-				.call();
-
-		// when
-		TreeWalk walk = new TreeWalk(db);
-		walk.addTree(c.getTree());
-		walk.addTree(c.getTree());
-		walk.addTree(c1.getTree());
-		List<ThreeWayDiffEntry> result = ThreeWayDiffEntry.scan(walk);
-
-		// then
-		assertThat(result, notNullValue());
-		assertThat(Integer.valueOf(result.size()), is(Integer.valueOf(1)));
-
-		ThreeWayDiffEntry entry = result.get(0);
-		assertThat(entry.getDirection(), is(Direction.INCOMING));
-		assertThat(entry.getChangeType(), is(ChangeType.MODIFY));
-		assertThat(entry.getPath(), is("a.txt"));
-	}
-
-	@Test
-	public void shouldListOutgoingModify() throws Exception {
-		// given
-		writeTrashFile("a.txt", "content");
-		Git git = new Git(db);
-		git.add().addFilepattern("a.txt").call();
-		RevCommit c = git.commit().setMessage("initial commit").call();
-		writeTrashFile("a.txt", "newe line");
-		RevCommit c1 = git.commit().setAll(true).setMessage("second commit")
-				.call();
-
-		// when
-		TreeWalk walk = new TreeWalk(db);
-		walk.addTree(c1.getTree());
-		walk.addTree(c.getTree());
-		walk.addTree(c.getTree());
-		List<ThreeWayDiffEntry> result = ThreeWayDiffEntry.scan(walk);
-
-		// then
-		assertThat(result, notNullValue());
-		assertThat(Integer.valueOf(result.size()), is(Integer.valueOf(1)));
-
-		ThreeWayDiffEntry entry = result.get(0);
-		assertThat(entry.getDirection(), is(Direction.OUTGOING));
-		assertThat(entry.getChangeType(), is(ChangeType.MODIFY));
-		assertThat(entry.getPath(), is("a.txt"));
-	}
-
-	@Test
-	public void shouldListConflictingModify() throws Exception {
-		// given
-		writeTrashFile("a.txt", "content");
-		Git git = new Git(db);
-		git.add().addFilepattern("a.txt").call();
-		RevCommit c = git.commit().setMessage("initial commit").call();
-		writeTrashFile("a.txt", "new line");
-		RevCommit c1 = git.commit().setAll(true).setMessage("second commit")
-				.call();
-
-		// when
-		TreeWalk walk = new TreeWalk(db);
-		walk.addTree(c1.getTree());
-		walk.addTree(c.getTree());
-		walk.addTree(c1.getTree());
-		List<ThreeWayDiffEntry> result = ThreeWayDiffEntry.scan(walk);
-
-		// then
-		assertThat(result, notNullValue());
-		assertThat(Integer.valueOf(result.size()), is(Integer.valueOf(1)));
-
-		ThreeWayDiffEntry entry = result.get(0);
-		assertThat(entry.getDirection(), is(Direction.CONFLICTING));
-		assertThat(entry.getChangeType(), is(ChangeType.MODIFY));
-		assertThat(entry.getPath(), is("a.txt"));
-	}
-
-	// copied from org.eclipse.jgit.lib.RepositoryTestCase
-	private File writeTrashFile(final String name, final String data)
-			throws IOException {
-		File path = new File(db.getWorkTree(), name);
-		write(path, data);
-		return path;
-	}
-
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/WorkingTreeChangeCacheTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/WorkingTreeChangeCacheTest.java
deleted file mode 100644
index 1e3260b..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/WorkingTreeChangeCacheTest.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2011, Dariusz Luksza <dariusz@luksza.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.synchronize;
-
-import static org.eclipse.jgit.junit.JGitTestUtil.deleteTrashFile;
-import static org.eclipse.jgit.junit.JGitTestUtil.writeTrashFile;
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertThat;
-
-import java.util.Map;
-
-import org.eclipse.egit.core.synchronize.GitCommitsModelCache.Change;
-import org.eclipse.jgit.api.Git;
-import org.junit.Test;
-
-@SuppressWarnings("boxing")
-public class WorkingTreeChangeCacheTest extends AbstractCacheTest {
-
-	@Test
-	public void shouldListSingleWorkspaceAddition() throws Exception {
-		// given
-		writeTrashFile(db, "a.txt", "trash");
-
-		// when
-		Map<String, Change> result = WorkingTreeChangeCache.build(db);
-
-		// then
-		assertThat(result.size(), is(1));
-		assertFileAddition(result, "a.txt", "a.txt");
-	}
-
-	@Test
-	public void shouldListTwoWorkspaceAdditions() throws Exception {
-		// given
-		writeTrashFile(db, "a.txt", "trash");
-		writeTrashFile(db, "b.txt", "trash");
-
-		// when
-		Map<String, Change> result = WorkingTreeChangeCache.build(db);
-
-		// then
-		assertThat(result.size(), is(2));
-		assertFileAddition(result, "a.txt", "a.txt");
-		assertFileAddition(result, "b.txt", "b.txt");
-	}
-
-	@Test
-	public void shouldListSingleWorkspaceAdditionInFolder() throws Exception {
-		// given
-		writeTrashFile(db, "folder/a.txt", "trash");
-
-		// when
-		Map<String, Change> result = WorkingTreeChangeCache.build(db);
-
-		// then
-		assertThat(result.size(), is(1));
-		assertFileAddition(result, "folder/a.txt", "a.txt");
-	}
-
-	@Test
-	public void shouldListTwoWorkspaceAdditionsInFolder() throws Exception {
-		// given
-		writeTrashFile(db, "folder/a.txt", "trash");
-		writeTrashFile(db, "folder/b.txt", "trash");
-
-		// when
-		Map<String, Change> result = WorkingTreeChangeCache.build(db);
-
-		// then
-		assertThat(result.size(), is(2));
-		assertFileAddition(result, "folder/a.txt", "a.txt");
-		assertFileAddition(result, "folder/b.txt", "b.txt");
-	}
-
-	@Test
-	public void shouldListSingleWorkspaceDeletion() throws Exception {
-		// given
-		writeTrashFile(db, "a.txt", "trash");
-		new Git(db).add().addFilepattern("a.txt").call();
-		deleteTrashFile(db, "a.txt");
-
-		// when
-		Map<String, Change> result = WorkingTreeChangeCache.build(db);
-
-		// then
-		assertThat(result.size(), is(1));
-		assertFileDeletion(result, "a.txt", "a.txt");
-	}
-
-	@Test
-	public void shouldListTwoWorkspaceDeletions() throws Exception {
-		// given
-		writeTrashFile(db, "a.txt", "trash");
-		writeTrashFile(db, "b.txt", "trash");
-		new Git(db).add().addFilepattern("a.txt").addFilepattern("b.txt").call();
-		deleteTrashFile(db, "a.txt");
-		deleteTrashFile(db, "b.txt");
-
-		// when
-		Map<String, Change> result = WorkingTreeChangeCache.build(db);
-
-		// then
-		assertThat(result.size(), is(2));
-		assertFileDeletion(result, "a.txt", "a.txt");
-		assertFileDeletion(result, "b.txt", "b.txt");
-	}
-
-	@Test
-	public void shouldListSingleWorkspaceDeletionInFolder() throws Exception {
-		// given
-		writeTrashFile(db, "folder/a.txt", "trash");
-		new Git(db).add().addFilepattern("folder/a.txt").call();
-		deleteTrashFile(db, "folder/a.txt");
-
-		// when
-		Map<String, Change> result = WorkingTreeChangeCache.build(db);
-
-		// then
-		assertThat(result.size(), is(1));
-		assertFileDeletion(result, "folder/a.txt", "a.txt");
-	}
-
-	@Test
-	public void shouldListTwoWorkspaceDeletionsInFolder() throws Exception {
-		// given
-		writeTrashFile(db, "folder/a.txt", "trash");
-		writeTrashFile(db, "folder/b.txt", "trash");
-		new Git(db).add().addFilepattern("folder/a.txt").addFilepattern("folder/b.txt").call();
-		deleteTrashFile(db, "folder/a.txt");
-		deleteTrashFile(db, "folder/b.txt");
-
-		// when
-		Map<String, Change> result = WorkingTreeChangeCache.build(db);
-
-		// then
-		assertThat(result.size(), is(2));
-		assertFileDeletion(result, "folder/a.txt", "a.txt");
-		assertFileDeletion(result, "folder/b.txt", "b.txt");
-	}
-
-	@Test
-	public void shouldListSingleWorkspaceChange() throws Exception {
-		// given
-		writeTrashFile(db, "a.txt", "trash");
-		new Git(db).add().addFilepattern("a.txt").call();
-		writeTrashFile(db, "a.txt", "modification");
-
-		// when
-		Map<String, Change> result = WorkingTreeChangeCache.build(db);
-
-		// then
-		assertThat(result.size(), is(1));
-		assertFileChange(result, "a.txt", "a.txt");
-	}
-
-	@Test
-	public void shouldListTwoWorkspaceChanges() throws Exception {
-		// given
-		writeTrashFile(db, "a.txt", "trash");
-		writeTrashFile(db, "b.txt", "trash");
-		new Git(db).add().addFilepattern("a.txt").addFilepattern("b.txt").call();
-		writeTrashFile(db, "a.txt", "modification");
-		writeTrashFile(db, "b.txt", "modification");
-
-		// when
-		Map<String, Change> result = WorkingTreeChangeCache.build(db);
-
-		// then
-		assertThat(result.size(), is(2));
-		assertFileChange(result, "a.txt", "a.txt");
-		assertFileChange(result, "b.txt", "b.txt");
-	}
-
-	@Test
-	public void shouldListSingleWorkspaceChangeInFolder() throws Exception {
-		// given
-		writeTrashFile(db, "folder/a.txt", "trash");
-		new Git(db).add().addFilepattern("folder/a.txt").call();
-		writeTrashFile(db, "folder/a.txt", "modification");
-
-		// when
-		Map<String, Change> result = WorkingTreeChangeCache.build(db);
-
-		// then
-		assertThat(result.size(), is(1));
-		assertFileChange(result, "folder/a.txt", "a.txt");
-	}
-
-	@Test
-	public void shouldListTwoWorkspaceChagneInFolder() throws Exception {
-		// given
-		writeTrashFile(db, "folder/a.txt", "trash");
-		writeTrashFile(db, "folder/b.txt", "trash");
-		new Git(db).add().addFilepattern("folder/a.txt").addFilepattern("folder/b.txt").call();
-		writeTrashFile(db, "folder/a.txt", "modification");
-		writeTrashFile(db, "folder/b.txt", "modification");
-
-		// when
-		Map<String, Change> result = WorkingTreeChangeCache.build(db);
-
-		// then
-		assertThat(result.size(), is(2));
-		assertFileChange(result, "folder/a.txt", "a.txt");
-		assertFileChange(result, "folder/b.txt", "b.txt");
-	}
-
-	@Test
-	public void shouldNotListIgnorefFile() throws Exception {
-		// given
-		writeTrashFile(db, "a.txt", "content");
-		writeTrashFile(db, ".gitignore", "a.txt");
-
-		// when
-		Map<String, Change> result = WorkingTreeChangeCache.build(db);
-
-		// then
-		assertThat(result.size(), is(1));
-		assertFileAddition(result, ".gitignore", ".gitignore");
-	}
-
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/dto/GitSynchronizeDataTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/dto/GitSynchronizeDataTest.java
deleted file mode 100644
index c33f646..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/synchronize/dto/GitSynchronizeDataTest.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2011, Dariusz Luksza <dariusz@luksza.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.synchronize.dto;
-
-import static org.eclipse.jgit.lib.Constants.HEAD;
-import static org.eclipse.jgit.lib.Constants.R_HEADS;
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertThat;
-
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.core.test.GitTestCase;
-import org.eclipse.egit.core.test.TestRepository;
-import org.eclipse.jgit.api.CreateBranchCommand.SetupUpstreamMode;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.lib.Repository;
-import org.junit.Before;
-import org.junit.Test;
-
-public class GitSynchronizeDataTest extends GitTestCase {
-
-	private Repository repo;
-
-	@Before
-	public void setUp() throws Exception {
-		super.setUp();
-
-		TestRepository testRepo = new TestRepository(gitDir);
-		testRepo.connect(project.project);
-		repo = RepositoryMapping.getMapping(project.project).getRepository();
-
-		// make initial commit
-		new Git(repo).commit().setAuthor("JUnit", "junit@jgit.org")
-				.setMessage("Initall commit").call();
-	}
-
-	@Test
-	public void shouldReturnSourceMergeForSymbolicRef() throws Exception {
-		// given
-		Git git = new Git(repo);
-		git.branchCreate().setName("test").setStartPoint("refs/heads/master")
-				.setUpstreamMode(SetupUpstreamMode.TRACK).call();
-		git.checkout().setName("test").call();
-		GitSynchronizeData gsd = new GitSynchronizeData(repo, HEAD, HEAD, false);
-
-		// when
-		String srcMerge = gsd.getSrcMerge();
-
-		// then
-		assertThat(srcMerge, is("refs/heads/master"));
-	}
-
-	@Test
-	public void shouldReturnSourceMergeForLocalRef() throws Exception {
-		// given
-		Git git = new Git(repo);
-		git.branchCreate().setName("test2").setStartPoint("refs/heads/master")
-				.setUpstreamMode(SetupUpstreamMode.TRACK).call();
-		git.checkout().setName("test2").call();
-		GitSynchronizeData gsd = new GitSynchronizeData(repo, R_HEADS + "test2",
-				HEAD, false);
-
-		// when
-		String srcMerge = gsd.getSrcMerge();
-
-		// then
-		assertThat(srcMerge, is("refs/heads/master"));
-	}
-
-	@Test
-	public void shouldReturnSourceMergeForRemoteBranch() throws Exception {
-		// given
-		Git git = new Git(repo);
-		git.branchCreate().setName("test3").setStartPoint("refs/heads/master")
-				.setUpstreamMode(SetupUpstreamMode.TRACK).call();
-		git.checkout().setName("test3").call();
-		repo.renameRef(R_HEADS + "test3", Constants.R_REMOTES + "origin/master").rename();
-		GitSynchronizeData gsd = new GitSynchronizeData(repo, "refs/remotes/origin/master",
-				HEAD, false);
-
-		// when
-		String srcMerge = gsd.getSrcMerge();
-
-		// then
-		assertThat(srcMerge, is("refs/heads/master"));
-	}
-
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/AdaptableFileTreeIteratorTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/AdaptableFileTreeIteratorTest.java
deleted file mode 100644
index e7615be..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/AdaptableFileTreeIteratorTest.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2009, Tor Arne Vestbø <torarnv@gmail.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.Set;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IWorkspaceRoot;
-import org.eclipse.egit.core.AdaptableFileTreeIterator;
-import org.eclipse.egit.core.ContainerTreeIterator;
-import org.eclipse.egit.core.op.ConnectProviderOperation;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.internal.storage.file.FileRepository;
-import org.eclipse.jgit.treewalk.TreeWalk;
-import org.eclipse.jgit.treewalk.WorkingTreeIterator;
-import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
-import org.junit.Before;
-import org.junit.Test;
-
-public class AdaptableFileTreeIteratorTest extends GitTestCase {
-
-	private Repository repository;
-
-	private File file;
-
-	@Before
-	public void setUp() throws Exception {
-		super.setUp();
-
-		repository = new FileRepository(gitDir);
-		repository.create();
-
-		file = new File(project.getProject().getLocation().toFile(), "a.txt");
-		final FileWriter fileWriter = new FileWriter(file);
-		fileWriter.write("aaaaaaaaaaa");
-		fileWriter.close();
-
-		final ConnectProviderOperation operation = new ConnectProviderOperation(
-				project.getProject(), gitDir);
-		operation.execute(null);
-	}
-
-	@Test
-	public void testFileTreeToContainerAdaptation() throws IOException {
-		final IWorkspaceRoot root = project.getProject().getWorkspace()
-				.getRoot();
-
-		final TreeWalk treeWalk = new TreeWalk(repository);
-		treeWalk.addTree(new AdaptableFileTreeIterator(repository, root));
-		treeWalk.setRecursive(true);
-
-		final IFile eclipseFile = project.getProject().getFile(file.getName());
-		final RepositoryMapping mapping = RepositoryMapping
-				.getMapping(eclipseFile);
-		final Set<String> repositoryPaths = Collections.singleton(mapping
-				.getRepoRelativePath(eclipseFile));
-
-		assertEquals(1, repositoryPaths.size());
-		treeWalk.setFilter(PathFilterGroup.createFromStrings(repositoryPaths));
-
-		assertTrue(treeWalk.next());
-
-		final WorkingTreeIterator iterator = treeWalk.getTree(0,
-				WorkingTreeIterator.class);
-		assertTrue(iterator instanceof ContainerTreeIterator);
-	}
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/ContainerTreeIteratorResourceFilterTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/ContainerTreeIteratorResourceFilterTest.java
deleted file mode 100644
index ca7a882..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/ContainerTreeIteratorResourceFilterTest.java
+++ /dev/null
@@ -1,244 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2012, Robin Stocker <robin@nibor.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.test;
-
-import static org.eclipse.core.resources.IResourceFilterDescription.EXCLUDE_ALL;
-import static org.eclipse.core.resources.IResourceFilterDescription.FILES;
-import static org.eclipse.core.resources.IResourceFilterDescription.FOLDERS;
-import static org.eclipse.core.resources.IResourceFilterDescription.INHERITABLE;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.hasItem;
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.eclipse.core.resources.FileInfoMatcherDescription;
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.core.AdaptableFileTreeIterator;
-import org.eclipse.egit.core.ContainerTreeIterator;
-import org.eclipse.egit.core.op.ConnectProviderOperation;
-import org.eclipse.jgit.internal.storage.file.FileRepository;
-import org.eclipse.jgit.treewalk.AbstractTreeIterator;
-import org.eclipse.jgit.treewalk.TreeWalk;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Test for how {@link ContainerTreeIterator} handles filtered resources.
- * <p>
- * The tricky thing is that they are not returned from API like
- * {@link IContainer#members()}. So we have to fall back to using an
- * {@link AdaptableFileTreeIterator} if there may be resource filters active.
- * <p>
- * In case of nested projects where the subproject is filtered in the parent
- * project with resource filters, we want the nested project to be walked with
- * {@link ContainerTreeIterator} again. That is, it should "recover" from
- * falling back to {@link AdaptableFileTreeIterator}.
- */
-public class ContainerTreeIteratorResourceFilterTest extends GitTestCase {
-
-	private FileRepository repository;
-
-	@Before
-	public void setUp() throws Exception {
-		super.setUp();
-
-		repository = new FileRepository(gitDir);
-		repository.create();
-
-		connectProject(project.getProject());
-	}
-
-	@Test
-	public void simpleNonInheritableFilter() throws Exception {
-		IProject p = project.getProject();
-		IFile filtered = testUtils.addFileToProject(p, "filtered.txt", "");
-		IFile unfiltered = testUtils.addFileToProject(p, "unfiltered.txt", "");
-		assertTrue("IFile should exist before filtering.", filtered.exists());
-		assertTrue("IFile should exist before filtering.", unfiltered.exists());
-
-		createFilter(p, EXCLUDE_ALL | FILES, "filtered.txt");
-		assertFalse("IFile should no longer exist after filtering.", filtered.exists());
-		assertTrue("IFile should exist after filtering.", unfiltered.exists());
-
-		List<Entry> entries = walkTree();
-
-		assertThat(entries, hasItem(containerTreeEntry("Project-1/filtered.txt")));
-		assertThat(entries, hasItem(containerTreeEntry("Project-1/unfiltered.txt")));
-	}
-
-	@Test
-	public void simpleNonInheritableFolderFilter() throws Exception {
-		IProject p = project.getProject();
-		IFile filtered = testUtils.addFileToProject(p, "folder/filtered.txt", "");
-		IFile unfiltered = testUtils.addFileToProject(p, "folder2/unfiltered.txt", "");
-
-		createFilter(p, EXCLUDE_ALL | FOLDERS, "folder");
-		assertFalse("IFile should no longer exist after filtering.", filtered.exists());
-		assertTrue("IFile should exist after filtering.", unfiltered.exists());
-
-		List<Entry> entries = walkTree();
-
-		assertThat(entries, hasItem(adaptableFileTreeEntry("Project-1/folder/filtered.txt")));
-		assertThat(entries, hasItem(containerTreeEntry("Project-1/folder2/unfiltered.txt")));
-	}
-
-	@Test
-	public void inheritableFilter() throws Exception {
-		IProject p = project.getProject();
-		IFile filtered1 = testUtils.addFileToProject(p, "folder1/filtered.txt", "");
-		IFile filtered2 = testUtils.addFileToProject(p, "folder1/folder2/filtered.txt", "");
-		IFile unfiltered = testUtils.addFileToProject(p, "folder1/folder2/unfiltered.txt", "");
-
-		createFilter(p, EXCLUDE_ALL | FILES | INHERITABLE, "filtered.txt");
-		assertFalse("IFile should no longer exist after filtering.", filtered1.exists());
-		assertFalse("IFile should no longer exist after filtering.", filtered2.exists());
-		assertTrue("IFile should exist after filtering.", unfiltered.exists());
-
-		List<Entry> entries = walkTree();
-
-		assertThat(entries, hasItem(containerTreeEntry("Project-1/folder1/filtered.txt")));
-		assertThat(entries, hasItem(containerTreeEntry("Project-1/folder1/folder2/filtered.txt")));
-		assertThat(entries, hasItem(containerTreeEntry("Project-1/folder1/folder2/unfiltered.txt")));
-	}
-
-	@Test
-	public void directlyNestedProject() throws Exception {
-		IProject p = project.getProject();
-		testUtils.addFileToProject(p, "file.txt", "");
-
-		TestProject testProject2 = new TestProject(true, "Project-1/Project-2");
-		testUtils.addFileToProject(testProject2.getProject(), "project2.txt", "");
-
-		createFilter(p, EXCLUDE_ALL | FOLDERS, "Project-2");
-
-		List<Entry> entries = walkTree();
-
-		assertThat(entries, hasItem(containerTreeEntry("Project-1/file.txt")));
-		// Should be handled by container tree iterator because it exists, even
-		// when it's not returned by members() of Project-1.
-		assertThat(entries, hasItem(containerTreeEntry("Project-1/Project-2/project2.txt")));
-	}
-
-	@Test
-	public void nestedProject() throws Exception {
-		IProject p = project.getProject();
-		testUtils.addFileToProject(p, "folder1/file.txt", "");
-		testUtils.addFileToProject(p, "folder1/subfolder/filtered.txt", "");
-
-		TestProject testProject2 = new TestProject(true, "Project-1/folder1/subfolder/Project-2");
-		connectProject(testProject2.getProject());
-		IFile project2File = testUtils.addFileToProject(testProject2.getProject(), "project2.txt", "");
-		assertThat(project2File.getProject(), is(testProject2.getProject()));
-
-		createFilter(p.getFolder("folder1"), EXCLUDE_ALL | FOLDERS, "subfolder");
-		assertFalse("IFolder should be filtered",
-				p.getFolder(new Path("folder1/subfolder")).exists());
-
-		List<Entry> entries = walkTree();
-
-		assertThat(entries, hasItem(containerTreeEntry("Project-1/folder1/file.txt")));
-		assertThat(entries, hasItem(adaptableFileTreeEntry("Project-1/folder1/subfolder/filtered.txt")));
-		// Should be handled by container tree iterator again, because the project exists.
-		assertThat(entries, hasItem(containerTreeEntry("Project-1/folder1/subfolder/Project-2/project2.txt")));
-
-		testProject2.dispose();
-	}
-
-	private static void createFilter(IContainer container, int type, String regexFilterArguments) throws CoreException {
-		FileInfoMatcherDescription matcherDescription = new FileInfoMatcherDescription(
-				"org.eclipse.core.resources.regexFilterMatcher",
-				regexFilterArguments);
-		container.createFilter(type, matcherDescription, 0, null);
-	}
-
-	private void connectProject(IProject p) throws CoreException {
-		final ConnectProviderOperation operation = new ConnectProviderOperation(
-				p, gitDir);
-		operation.execute(null);
-	}
-
-	private List<Entry> walkTree() throws IOException {
-		TreeWalk treeWalk = new TreeWalk(repository);
-		ContainerTreeIterator tree = new ContainerTreeIterator(repository, project.getProject());
-		int treeIndex = treeWalk.addTree(tree);
-		treeWalk.setRecursive(true);
-		List<Entry> entries = new ArrayList<Entry>();
-		while (treeWalk.next()) {
-			AbstractTreeIterator it = treeWalk.getTree(treeIndex, AbstractTreeIterator.class);
-			Entry entry = new Entry(treeWalk.getPathString(), it.getClass());
-			entries.add(entry);
-		}
-		return entries;
-	}
-
-	private static Entry containerTreeEntry(String path) {
-		return new Entry(path, ContainerTreeIterator.class);
-	}
-
-	private static Entry adaptableFileTreeEntry(String path) {
-		return new Entry(path, AdaptableFileTreeIterator.class);
-	}
-
-	// Value object (case class).
-	private static class Entry {
-		private final String path;
-		private Class<? extends AbstractTreeIterator> iteratorClass;
-
-		public Entry(String path, Class<? extends AbstractTreeIterator> iteratorClass) {
-			this.path = path;
-			this.iteratorClass = iteratorClass;
-		}
-
-		@Override
-		public String toString() {
-			return path + " (" + iteratorClass.getSimpleName() + ")";
-		}
-
-		@Override
-		public int hashCode() {
-			final int prime = 31;
-			int result = 1;
-			result = prime * result
-					+ ((iteratorClass == null) ? 0 : iteratorClass.hashCode());
-			result = prime * result + ((path == null) ? 0 : path.hashCode());
-			return result;
-		}
-
-		@Override
-		public boolean equals(Object obj) {
-			if (this == obj)
-				return true;
-			if (obj == null)
-				return false;
-			if (getClass() != obj.getClass())
-				return false;
-			Entry other = (Entry) obj;
-			if (iteratorClass == null) {
-				if (other.iteratorClass != null)
-					return false;
-			} else if (!iteratorClass.equals(other.iteratorClass))
-				return false;
-			if (path == null) {
-				if (other.path != null)
-					return false;
-			} else if (!path.equals(other.path))
-				return false;
-			return true;
-		}
-	}
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/DualRepositoryTestCase.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/DualRepositoryTestCase.java
deleted file mode 100644
index 641f9f7..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/DualRepositoryTestCase.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2010, 2012 Mathias Kinzler <mathias.kinzler@sap.com> and others.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.test;
-
-import java.io.File;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IProjectDescription;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.op.ConnectProviderOperation;
-import org.junit.After;
-import org.junit.Before;
-
-public abstract class DualRepositoryTestCase {
-
-	protected TestUtils testUtils = new TestUtils();
-
-	protected TestRepository repository1;
-
-	protected TestRepository repository2;
-
-	protected IProject testProject;
-
-	@Before
-	public void beforeTestCase() throws Exception {
-		// ensure there are no shared Repository instances left
-		// when starting a new test
-		Activator.getDefault().getRepositoryCache().clear();
-	}
-
-	@After
-	public void afterTestCase() throws Exception {
-		Activator.getDefault().getRepositoryCache().clear();
-		if (repository1 != null)
-			repository1.dispose();
-		if (repository2 != null)
-			repository2.dispose();
-		if (testProject != null)
-			testProject.delete(false, false, null);
-		testUtils.deleteTempDirs();
-	}
-
-	protected IProject importProject(TestRepository repo, String projectName)
-			throws Exception {
-		IProject firstProject = ResourcesPlugin.getWorkspace().getRoot()
-				.getProject(projectName);
-		if (firstProject.exists())
-			firstProject.delete(false, null);
-		IProjectDescription desc = ResourcesPlugin.getWorkspace()
-				.newProjectDescription(projectName);
-		File parentFile = repo.getRepository().getWorkTree();
-		desc.setLocation(new Path(new File(parentFile, projectName).getPath()));
-		firstProject.create(desc, null);
-		firstProject.open(null);
-		ConnectProviderOperation cop = new ConnectProviderOperation(
-				firstProject, repo.getRepository().getDirectory());
-		cop.execute(null);
-		return firstProject;
-	}
-
-
-
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/EclipseGitProgressTransformerTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/EclipseGitProgressTransformerTest.java
deleted file mode 100644
index 50f47b2..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/EclipseGitProgressTransformerTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2011, Adrian G&ouml;rler <adrian.goerler@sap.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.test;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.egit.core.EclipseGitProgressTransformer;
-import org.eclipse.jgit.lib.ProgressMonitor;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.runners.MockitoJUnitRunner;
-
-@RunWith(MockitoJUnitRunner.class)
-public class EclipseGitProgressTransformerTest {
-
-	@Mock
-	IProgressMonitor eclipseMonitor;
-
-	ProgressMonitor classUnderTest;
-
-	@Before
-	public void setup() {
-		classUnderTest = new EclipseGitProgressTransformer(eclipseMonitor);
-	}
-
-	@Test
-	public void testUnboundedMonitor() {
-		final String title = "Title";
-
-		classUnderTest.beginTask(title, ProgressMonitor.UNKNOWN);
-		Mockito.verify(eclipseMonitor).subTask("Title");
-
-		classUnderTest.update(10);
-		classUnderTest.update(0);
-		Mockito.verify(eclipseMonitor, Mockito.times(1)).subTask("Title, 10");
-		classUnderTest.update(20);
-		Mockito.verify(eclipseMonitor).subTask("Title, 30");
-
-	}
-
-	@Test
-	public void testBoundedMonitor() {
-		final String title = "Title";
-
-		classUnderTest.beginTask(title, 50);
-		Mockito.verify(eclipseMonitor).subTask("Title");
-
-		classUnderTest.update(10);
-		classUnderTest.update(0);
-		Mockito.verify(eclipseMonitor, Mockito.times(1)).subTask("Title:                    20% (10/50)");
-		classUnderTest.update(20);
-		Mockito.verify(eclipseMonitor).subTask("Title:                    60% (30/50)");
-
-	}
-
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/GitProjectSetCapabilityTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/GitProjectSetCapabilityTest.java
deleted file mode 100644
index 82b183b..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/GitProjectSetCapabilityTest.java
+++ /dev/null
@@ -1,321 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2011, 2012 Robin Stocker <robin@nibor.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IProjectDescription;
-import org.eclipse.core.resources.IWorkspaceRoot;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.GitProjectSetCapability;
-import org.eclipse.egit.core.RepositoryUtil;
-import org.eclipse.egit.core.op.ConnectProviderOperation;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.lib.ConfigConstants;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.internal.storage.file.FileRepository;
-import org.eclipse.jgit.util.FileUtils;
-import org.eclipse.team.core.ProjectSetSerializationContext;
-import org.eclipse.team.core.TeamException;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class GitProjectSetCapabilityTest {
-
-	private GitProjectSetCapability capability;
-
-	private List<IProject> createdProjects = new ArrayList<IProject>();
-	private List<File> pathsToClean = new ArrayList<File>();
-
-	@Before
-	public void setUp() {
-		Activator.getDefault().getRepositoryCache().clear();
-		capability = new GitProjectSetCapability();
-	}
-
-	@After
-	public void tearDown() throws Exception {
-		Activator.getDefault().getRepositoryCache().clear();
-		for (IProject project : createdProjects)
-			if (project.exists())
-				project.delete(true, true, null);
-		for (File pathToClean : pathsToClean)
-			if (pathToClean.exists())
-				FileUtils.delete(pathToClean, FileUtils.RECURSIVE | FileUtils.RETRY);
-	}
-
-	@Test
-	public void testExport() throws Exception {
-		IProject aProject = createProject("a");
-		File aRepo = createRepository(aProject.getLocation(), "http://example.org/repo-a", "master");
-		connectProject(aProject, aRepo);
-
-		IPath bPath = ResourcesPlugin.getWorkspace().getRoot().getLocation().append("b");
-		File bRepo = createRepository(bPath, "http://example.org/repo-b", "master");
-		IProject baProject = createProject(bPath, "ba");
-		IProject bbProject = createProject(bPath, "bb");
-		connectProject(baProject, bRepo);
-		connectProject(bbProject, bRepo);
-		pathsToClean.add(bPath.toFile());
-
-		IProject cProject = createProject("c");
-		File cRepo = createRepository(cProject.getLocation(), "http://example.org/repo-c", "stable");
-		connectProject(cProject, cRepo);
-
-		IProject[] projects = new IProject[] { aProject, baProject, bbProject, cProject };
-		String[] references = capability.asReference(
-				projects, new ProjectSetSerializationContext(), new NullProgressMonitor());
-		assertEquals(4, references.length);
-		assertEquals("1.0,http://example.org/repo-a,master,.", references[0]);
-		assertEquals("1.0,http://example.org/repo-b,master,ba", references[1]);
-		assertEquals("1.0,http://example.org/repo-b,master,bb", references[2]);
-		assertEquals("1.0,http://example.org/repo-c,stable,.", references[3]);
-	}
-
-	@Test
-	public void testImport() throws Exception {
-		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
-		IPath reposPath = root.getLocation().append("repos");
-		pathsToClean.add(reposPath.toFile());
-
-		IPath aPath = reposPath.append("a");
-		IProject aProject = createProject(reposPath, "a");
-		createRepository(aPath, "notused", "master");
-		aProject.delete(false, true, null);
-
-		IPath bPath = reposPath.append("b");
-		IProject baProject = createProject(bPath, "ba");
-		IProject bbProject = createProject(bPath, "bb");
-		createRepository(bPath, "notused", "master");
-		baProject.delete(false, true, null);
-		bbProject.delete(false, true, null);
-
-		IPath cPath = reposPath.append("c");
-		IProject cProject = createProject(reposPath, "c");
-		createRepository(cPath, "notused", "stable");
-		cProject.delete(false, true, null);
-
-		String aReference = "1.0," + aPath.toFile().toURI().toString() + ",master,.";
-		String baReference = "1.0," + bPath.toFile().toURI().toString() + ",master,ba";
-		String bbReference = "1.0," + bPath.toFile().toURI().toString() + ",master,bb";
-		String cReference = "1.0," + cPath.toFile().toURI().toString() + ",stable,.";
-		String[] references = new String[] { aReference, baReference, bbReference, cReference };
-
-		addToWorkspace(references);
-
-		pathsToClean.add(root.getLocation().append("b").toFile());
-
-		IProject aImported = root.getProject("a");
-		createdProjects.add(aImported);
-		assertTrue(aImported.exists());
-		assertNotNull(RepositoryMapping.getMapping(aImported));
-
-		IProject baImported = root.getProject("ba");
-		createdProjects.add(baImported);
-		assertTrue(baImported.exists());
-		assertEquals(root.getLocation().append("b/ba"), baImported.getLocation());
-		assertNotNull(RepositoryMapping.getMapping(baImported));
-
-		IProject bbImported = root.getProject("bb");
-		createdProjects.add(bbImported);
-		assertTrue(bbImported.exists());
-		assertEquals(root.getLocation().append("b/bb"), bbImported.getLocation());
-		assertNotNull(RepositoryMapping.getMapping(bbImported));
-
-		IProject cImported = root.getProject("c");
-		createdProjects.add(cImported);
-		assertTrue(cImported.exists());
-		RepositoryMapping cMapping = RepositoryMapping.getMapping(cImported);
-		assertNotNull(cMapping);
-		assertEquals("stable", cMapping.getRepository().getBranch());
-	}
-
-	@Test
-	public void testImportWithDifferentBranchesOfSameRepo() throws Exception {
-		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
-		IPath reposPath = root.getLocation().append("repos");
-		pathsToClean.add(reposPath.toFile());
-
-		IPath xPath = reposPath.append("x");
-		IProject xaProject = createProject(xPath, "xa");
-		IProject xbProject = createProject(xPath, "xb");
-		createRepository(xPath, "notused", "stable");
-		xaProject.delete(false, true, null);
-		xbProject.delete(false, true, null);
-
-		String xaMasterReference = "1.0," + xPath.toFile().toURI().toString() + ",master,xa";
-		String xbStableReference = "1.0," + xPath.toFile().toURI().toString() + ",stable,xb";
-		String[] references = new String[] { xaMasterReference, xbStableReference };
-
-		addToWorkspace(references);
-
-		pathsToClean.add(root.getLocation().append("x").toFile());
-		pathsToClean.add(root.getLocation().append("x_stable").toFile());
-
-		IProject xaImported = root.getProject("xa");
-		createdProjects.add(xaImported);
-		assertTrue(xaImported.exists());
-		assertEquals(root.getLocation().append("x/xa"), xaImported.getLocation());
-		RepositoryMapping xaMapping = RepositoryMapping.getMapping(xaImported);
-		assertNotNull(xaMapping);
-		assertEquals("master", xaMapping.getRepository().getBranch());
-
-		IProject xbImported = root.getProject("xb");
-		createdProjects.add(xbImported);
-		assertTrue(xbImported.exists());
-		assertEquals(root.getLocation().append("x_stable/xb"), xbImported.getLocation());
-		RepositoryMapping xbMapping = RepositoryMapping.getMapping(xbImported);
-		assertNotNull(xbMapping);
-		assertEquals("stable", xbMapping.getRepository().getBranch());
-	}
-
-	@Test
-	public void testImportWithMultipleCallsForSameDestinationRepo() throws Exception {
-		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
-		IPath reposPath = root.getLocation().append("repos");
-		pathsToClean.add(reposPath.toFile());
-
-		IPath xPath = reposPath.append("x");
-		IProject xaProject = createProject(xPath, "xa");
-		IProject xbProject = createProject(xPath, "xb");
-		String url = createUrl(xPath);
-		createRepository(xPath, url, "stable");
-		xaProject.delete(false, true, null);
-		xbProject.delete(false, true, null);
-
-		String xaReference = createProjectReference(xPath, "master", "xa");
-		String xbReference = createProjectReference(xPath, "master", "xb");
-
-		// This should work because there is not yet a repo at the destination
-		addToWorkspace(new String[] { xaReference });
-
-		// This should work because the repo that is already there is for the
-		// same remote URL. It's assumed to be ok and will skip cloning and
-		// directly import the project.
-		addToWorkspace(new String[] { xbReference });
-
-		pathsToClean.add(root.getLocation().append("x").toFile());
-
-		IPath otherPathWithX = reposPath.append("other").append("x");
-		String otherReferenceWithDifferentUrl = createProjectReference(otherPathWithX, "master", "xb");
-
-		try {
-			capability.addToWorkspace(new String[] { otherReferenceWithDifferentUrl },
-					new ProjectSetSerializationContext(),
-					new NullProgressMonitor());
-			fail("Should throw TeamException when a repo exists at the place but doesn't have the same URL.");
-		} catch (TeamException e) {
-			// This is expected
-		}
-	}
-
-	@Test
-	public void testImportWhereRepoAlreadyExistsAtDifferentLocation() throws Exception {
-		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
-		IPath reposPath = root.getLocation().append("existingbutdifferent");
-		pathsToClean.add(reposPath.toFile());
-
-		IPath repoPath = reposPath.append("repo");
-		IProject project = createProject(repoPath, "project");
-		project.delete(false, true, null);
-		String url = createUrl(repoPath);
-		File repoDir = createRepository(repoPath, url, "master");
-
-		IPath otherRepoPath = reposPath.append("other");
-		File otherRepoDir = createRepository(otherRepoPath, "other-url", "master");
-
-		RepositoryUtil util = Activator.getDefault().getRepositoryUtil();
-		util.addConfiguredRepository(repoDir);
-		util.addConfiguredRepository(otherRepoDir);
-
-		String reference = createProjectReference(repoPath, "master", "project");
-
-		addToWorkspace(new String[] { reference });
-
-		IProject imported = root.getProject("project");
-		assertEquals("Expected imported project to be from already existing repository",
-				root.getLocation().append("existingbutdifferent/repo/project"), imported.getLocation());
-	}
-
-	private IProject createProject(String name) throws CoreException {
-		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
-		IProject p = root.getProject(name);
-		p.create(null);
-		p.open(null);
-
-		createdProjects.add(p);
-		return p;
-	}
-
-	private IProject createProject(IPath parentLocation, String name) throws CoreException {
-		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
-
-		IProject p = root.getProject(name);
-		IProjectDescription projectDescription = ResourcesPlugin.getWorkspace().newProjectDescription(p.getName());
-		projectDescription.setLocation(parentLocation.append(name));
-		p.create(projectDescription, null);
-		p.open(null);
-
-		createdProjects.add(p);
-		return p;
-	}
-
-	private File createRepository(IPath location, String url, String branch) throws Exception {
-		File gitDirectory = new File(location.toFile(), Constants.DOT_GIT);
-		Repository repo = new FileRepository(gitDirectory);
-		repo.getConfig().setString(ConfigConstants.CONFIG_REMOTE_SECTION, "origin", ConfigConstants.CONFIG_KEY_URL, url);
-		repo.getConfig().setString(ConfigConstants.CONFIG_BRANCH_SECTION, branch, ConfigConstants.CONFIG_KEY_REMOTE, "origin");
-		repo.create();
-		repo.close();
-
-		Git git = new Git(repo);
-		git.add().addFilepattern(".").call();
-		git.commit().setMessage("initial").call();
-		if (!branch.equals("master"))
-			git.checkout().setName(branch).setCreateBranch(true).call();
-
-		pathsToClean.add(gitDirectory);
-		return gitDirectory;
-	}
-
-	private void connectProject(IProject project, File gitDir) throws CoreException {
-		ConnectProviderOperation operation = new ConnectProviderOperation(
-				project.getProject(), gitDir);
-		operation.execute(null);
-	}
-
-	private static String createProjectReference(IPath repoPath, String branch, String projectPath) {
-		return "1.0," + createUrl(repoPath) + "," + branch + "," + projectPath;
-	}
-
-	private static String createUrl(IPath repoPath) {
-		return repoPath.toFile().toURI().toString();
-	}
-
-	private void addToWorkspace(String[] references) throws TeamException {
-		capability.addToWorkspace(references,
-				new ProjectSetSerializationContext(),
-				new NullProgressMonitor());
-	}
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/GitResourceDeltaTestHelper.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/GitResourceDeltaTestHelper.java
deleted file mode 100644
index 464897c..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/GitResourceDeltaTestHelper.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2013, François Rey <eclipse.org_@_francois_._rey_._name>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *    François Rey - First implementation as part of handling linked resources
- *******************************************************************************/
-package org.eclipse.egit.core.test;
-
-import static org.hamcrest.Matchers.hasItem;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThat;
-
-import java.util.Collection;
-import java.util.HashSet;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IResourceChangeEvent;
-import org.eclipse.core.resources.IResourceChangeListener;
-import org.eclipse.core.resources.IResourceDelta;
-import org.eclipse.core.resources.IResourceDeltaVisitor;
-import org.eclipse.core.resources.IWorkspaceRoot;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.internal.indexdiff.GitResourceDeltaVisitor;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.jgit.lib.Repository;
-
-/**
- * Helper class for test cases that need to know what workspace changes egit
- * will detect. Changes to files within the git repository folder are ignored
- * by default, however this behavior can be changed by a constructor parameter.
- * Usage: create one instance per test case and call {@link #setUp()} and
- * {@link #tearDown()} before and after the test case. Use other functions
- * to test and assert what changed resources are expected.
- * Implementation is mainly an {@link IResourceChangeListener} which calls
- * a {@link GitResourceDeltaVisitor} for each change that occurs in a project
- * that uses egit.
- */
-public class GitResourceDeltaTestHelper {
-	private Repository repository;
-
-	private IResourceChangeListener resourceChangeListener;
-
-	private final Collection<IResource> changedResources;
-
-	private final boolean ignoreTeamPrivateMember;
-
-	public GitResourceDeltaTestHelper(Repository repository) {
-		this(repository, true);
-	}
-
-	public GitResourceDeltaTestHelper(Repository repository,
-			boolean ignoreTeamPrivateMember) {
-		this.repository = repository;
-		this.changedResources = new HashSet<IResource>();
-		this.ignoreTeamPrivateMember = ignoreTeamPrivateMember;
-	}
-
-	public void setUp() {
-		resourceChangeListener = new IResourceChangeListener() {
-			public void resourceChanged(final IResourceChangeEvent event) {
-				try {
-					event.getDelta().accept(new IResourceDeltaVisitor() {
-						public boolean visit(IResourceDelta delta)
-								throws CoreException {
-							final IResource resource = delta.getResource();
-							IProject project = resource.getProject();
-							if (project == null)
-								return true;
-							RepositoryMapping mapping = RepositoryMapping
-									.getMapping(resource);
-							if (mapping == null)
-								return true;
-							if (mapping.getRepository() != repository)
-								return false;
-							GitResourceDeltaVisitor visitor = new GitResourceDeltaVisitor(
-									repository);
-							try {
-								event.getDelta().accept(visitor);
-							} catch (CoreException e) {
-								Activator.logError(e.getMessage(), e);
-								return false;
-							}
-							IPath gitDirAbsolutePath = mapping
-									.getGitDirAbsolutePath();
-							for (IResource res : visitor.getResourcesToUpdate()) {
-								if (ignoreTeamPrivateMember
-										&& (res.isTeamPrivateMember() || gitDirAbsolutePath
-												.isPrefixOf(res
-														.getRawLocation()
-														.makeAbsolute())))
-									continue;
-								changedResources.add(res);
-							}
-							return false;
-						}
-					});
-				} catch (CoreException e) {
-					Activator.logError(e.getMessage(), e);
-					return;
-				}
-			}
-		};
-		ResourcesPlugin.getWorkspace().addResourceChangeListener(
-				resourceChangeListener, IResourceChangeEvent.POST_CHANGE);
-	}
-
-	public void tearDown() {
-		if (resourceChangeListener != null) {
-			ResourcesPlugin.getWorkspace().removeResourceChangeListener(
-					resourceChangeListener);
-			resourceChangeListener = null;
-		}
-	}
-
-	public Collection<IResource> getChangedResources() {
-		return changedResources;
-	}
-
-	public boolean noChangedResources() {
-		return changedResources.isEmpty();
-	}
-
-	public boolean anyChangedResources() {
-		return !changedResources.isEmpty();
-	}
-
-	public void assertChangedResources(String[] expected) {
-		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
-		for (String file : expected)
-			assertThat(changedResources, hasItem(root.findMember(file)));
-		assertEquals(expected.length, changedResources.size());
-	}
-}
\ No newline at end of file
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/GitTestCase.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/GitTestCase.java
deleted file mode 100644
index bba9ab1..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/GitTestCase.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2007, 2013 Robin Rosenberg <robin.rosenberg@dewire.com> and others.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.test;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.FileWriter;
-import java.io.IOException;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.preferences.IEclipsePreferences;
-import org.eclipse.core.runtime.preferences.InstanceScope;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.GitCorePreferences;
-import org.eclipse.jgit.junit.MockSystemReader;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.ObjectInserter;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.util.FileUtils;
-import org.eclipse.jgit.util.IO;
-import org.eclipse.jgit.util.SystemReader;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.BeforeClass;
-
-public abstract class GitTestCase {
-
-	protected final TestUtils testUtils = new TestUtils();
-
-	protected TestProject project;
-
-	protected File gitDir;
-
-	@BeforeClass
-	public static void setUpClass() {
-		// suppress auto-ignoring and auto-sharing to avoid interference
-		IEclipsePreferences p = InstanceScope.INSTANCE.getNode(Activator
-				.getPluginId());
-		p.putBoolean(GitCorePreferences.core_autoIgnoreDerivedResources, false);
-		p.putBoolean(GitCorePreferences.core_autoShareProjects, false);
-	}
-
-	@Before
-	public void setUp() throws Exception {
-		// ensure there are no shared Repository instances left
-		// when starting a new test
-		Activator.getDefault().getRepositoryCache().clear();
-		MockSystemReader mockSystemReader = new MockSystemReader();
-		SystemReader.setInstance(mockSystemReader);
-		mockSystemReader.setProperty(Constants.GIT_CEILING_DIRECTORIES_KEY,
-				ResourcesPlugin.getWorkspace().getRoot().getLocation().toFile()
-						.getAbsoluteFile().toString());
-		project = new TestProject(true);
-		gitDir = new File(project.getProject().getWorkspace().getRoot()
-				.getRawLocation().toFile(), Constants.DOT_GIT);
-		if (gitDir.exists())
-			FileUtils.delete(gitDir, FileUtils.RECURSIVE | FileUtils.RETRY);
-	}
-
-	@After
-	public void tearDown() throws Exception {
-		project.dispose();
-		Activator.getDefault().getRepositoryCache().clear();
-		if (gitDir.exists())
-			FileUtils.delete(gitDir, FileUtils.RECURSIVE | FileUtils.RETRY);
-	}
-
-	protected ObjectId createFile(Repository repository, IProject actProject, String name, String content) throws IOException {
-		File file = new File(actProject.getProject().getLocation().toFile(), name);
-		FileWriter fileWriter = new FileWriter(file);
-		fileWriter.write(content);
-		fileWriter.close();
-		byte[] fileContents = IO.readFully(file);
-		ObjectInserter inserter = repository.newObjectInserter();
-		try {
-			ObjectId objectId = inserter.insert(Constants.OBJ_BLOB, fileContents);
-			inserter.flush();
-			return objectId;
-		} finally {
-			inserter.release();
-		}
-	}
-
-	protected ObjectId createFileCorruptShort(Repository repository,
-			IProject actProject, String name, String content)
-			throws IOException {
-		ObjectId id = createFile(repository, actProject, name, content);
-		File file = new File(repository.getDirectory(), "objects/"
-				+ id.name().substring(0, 2) + "/" + id.name().substring(2));
-		byte[] readFully = IO.readFully(file);
-		FileUtils.delete(file);
-		FileOutputStream fileOutputStream = new FileOutputStream(file);
-		byte[] truncatedData = new byte[readFully.length - 1];
-		System.arraycopy(readFully, 0, truncatedData, 0, truncatedData.length);
-		fileOutputStream.write(truncatedData);
-		fileOutputStream.close();
-		return id;
-	}
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/GitURITest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/GitURITest.java
deleted file mode 100644
index 983f7da..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/GitURITest.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2011, IBM Corporation
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *    Tomasz Zarna (IBM) - initial implementation
- *******************************************************************************/
-package org.eclipse.egit.core.test;
-
-import static org.junit.Assert.assertEquals;
-
-import java.net.URI;
-import java.util.HashMap;
-
-import org.eclipse.egit.core.GitProjectSetCapability;
-import org.eclipse.egit.core.internal.GitURI;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.transport.URIish;
-import org.junit.Before;
-import org.junit.Test;
-
-public class GitURITest {
-
-	private GitProjectSetCapability capability;
-
-	@Before
-	public void setUp() {
-		capability = new GitProjectSetCapability();
-	}
-
-	@Test(expected = IllegalArgumentException.class)
-	public void testInvalidScmUriWithQuotationMarks() throws Exception {
-		URI.create("scm:git:git://git.eclipse.org/gitroot/platform/eclipse.platform.team.git;path=\"bundles/org.eclipse.team.core\"");
-		// expected IAE, " are not allowed in a URI reference
-	}
-
-	@Test(expected = IllegalArgumentException.class)
-	public void testInvalidScmUriForCVS() throws Exception {
-		new GitURI(URI.create("scm:cvs:pserver:dev.eclipse.org:/cvsroot/eclipse:org.eclipse.compare"));
-		// expected IAE, it's a CVS SCM URL
-	}
-
-	// ScmUrlImportDescription can handle " in Strings expected to be URI refs
-	@Test
-	public void testScmUriWithPath() throws Exception {
-		ScmUrlImportDescription description = new ScmUrlImportDescription(
-				"scm:git:git://git.eclipse.org/gitroot/platform/eclipse.platform.team.git;path=\"bundles/org.eclipse.team.core\"",
-				null);
-		URI uri = description.getUri();
-		GitURI gitUri = new GitURI(uri);
-		assertEquals("bundles/org.eclipse.team.core", gitUri.getPath()
-				.toString());
-		URIish uriish = new URIish(
-				"git://git.eclipse.org/gitroot/platform/eclipse.platform.team.git");
-		assertEquals(uriish, gitUri.getRepository());
-		assertEquals(Constants.MASTER, gitUri.getTag());
-
-		String refString = capability.asReference(uri, "org.eclipse.team.core");
-		assertEquals(
-				"1.0,git://git.eclipse.org/gitroot/platform/eclipse.platform.team.git,master,bundles/org.eclipse.team.core",
-				refString);
-	}
-
-	@Test
-	public void testScmUriWithPathAndTag() throws Exception {
-		ScmUrlImportDescription description = new ScmUrlImportDescription(
-				"scm:git:git://git.eclipse.org/gitroot/platform/eclipse.platform.ui.git;path=\"bundles/org.eclipse.jface\";tag=v20111107-2125",
-				null);
-		URI uri = description.getUri();
-		GitURI gitUri = new GitURI(uri);
-		assertEquals("bundles/org.eclipse.jface", gitUri.getPath().toString());
-		URIish uriish = new URIish(
-				"git://git.eclipse.org/gitroot/platform/eclipse.platform.ui.git");
-		assertEquals(uriish, gitUri.getRepository());
-		assertEquals("v20111107-2125", gitUri.getTag());
-
-		String refString = capability.asReference(uri, "org.eclipse.jface");
-		assertEquals(
-				"1.0,git://git.eclipse.org/gitroot/platform/eclipse.platform.ui.git,v20111107-2125,bundles/org.eclipse.jface",
-				refString);
-	}
-
-	@Test
-	public void testScmUriWithPathProjectAndTag() throws Exception {
-		ScmUrlImportDescription description = new ScmUrlImportDescription(
-				"scm:git:git://git.eclipse.org/gitroot/equinox/rt.equinox.bundles.git;path=\"bundles/org.eclipse.equinox.http.jetty6\";project=\"org.eclipse.equinox.http.jetty\";tag=v20111010-1614",
-				null);
-		URI uri = description.getUri();
-		GitURI gitUri = new GitURI(uri);
-		assertEquals("bundles/org.eclipse.equinox.http.jetty6", gitUri
-				.getPath().toString());
-		URIish uriish = new URIish(
-				"git://git.eclipse.org/gitroot/equinox/rt.equinox.bundles.git");
-		assertEquals(uriish, gitUri.getRepository());
-		assertEquals("v20111010-1614", gitUri.getTag());
-		assertEquals("org.eclipse.equinox.http.jetty", gitUri.getProjectName());
-
-		String refString = capability.asReference(uri,
-				"org.eclipse.equinox.http.jetty");
-		assertEquals(
-				"1.0,git://git.eclipse.org/gitroot/equinox/rt.equinox.bundles.git,v20111010-1614,bundles/org.eclipse.equinox.http.jetty6",
-				refString);
-	}
-
-	// TODO remove this copy of org.eclipse.team.core.ScmUrlImportDescription
-	// when we drop support for Galileo
-	/**
-	 * Copy of org.eclipse.team.core.ScmUrlImportDescription to support tests until
-	 * we drop support for Galileo. DON'T USE OUTSIDE OF TEST BUNDLE!
-	 *
-	 * Describes how a bundle import will be executed. A bundle importer delegate
-	 * creates bundle import descriptions when it validates bundle manifests for
-	 * importing. The result, a set of bundle import descriptions is then passed to
-	 * TeamUI, which basing on the info from the descriptions instantiate and
-	 * initialize IScmUrlImportWizardPage pages. The pages can be used to alter the
-	 * default import configuration e.g. for bundles stored in a CVS repository the
-	 * user may want to check out HEAD rather than a specific version.
-	 * <p>
-	 * <strong>EXPERIMENTAL</strong>. This class has been added as part of a work in
-	 * progress. There is no guarantee that this API will work or that it will
-	 * remain the same. Please do not use this API without consulting with the Team
-	 * team.
-	 *
-	 * @since 3.6
-	 */
-	protected static class ScmUrlImportDescription {
-		private String url;
-		private String project;
-		private HashMap properties;
-
-		public ScmUrlImportDescription(String url, String project) {
-			this.url = url;
-			this.project = project;
-		}
-
-		/**
-		 * @return project name
-		 */
-		public String getProject() {
-			return project;
-		}
-
-		/**
-		 * SCM URL
-		 *
-		 * @return a string representation of the SCM URL
-		 */
-		public String getUrl() {
-			return url;
-		}
-
-		public URI getUri() {
-			return URI.create(url.replaceAll("\"", "")); //$NON-NLS-1$//$NON-NLS-2$
-		}
-
-		public void setUrl(String url) {
-			this.url = url;
-		}
-
-		/**
-		 * Sets or removes a client property.
-		 *
-		 * @param key
-		 *            property key
-		 * @param value
-		 *            property value or <code>null</code> to remove the property
-		 */
-		public synchronized void setProperty(String key, Object value) {
-			if (properties == null) {
-				properties = new HashMap();
-			}
-			if (value == null) {
-				properties.remove(key);
-			} else {
-				properties.put(key, value);
-			}
-
-		}
-
-		/**
-		 * Returns the specified client property, or <code>null</code> if none.
-		 *
-		 * @param key
-		 *            property key
-		 * @return property value or <code>null</code>
-		 */
-		public synchronized Object getProperty(String key) {
-			if (properties == null) {
-				return null;
-			}
-			return properties.get(key);
-		}
-	}
-
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/JobSchedulingAssert.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/JobSchedulingAssert.java
deleted file mode 100644
index f461e13..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/JobSchedulingAssert.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2012, Robin Stocker <robin@nibor.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.test;
-
-import static org.junit.Assert.assertTrue;
-
-import org.eclipse.core.runtime.jobs.IJobChangeEvent;
-import org.eclipse.core.runtime.jobs.IJobManager;
-import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.core.runtime.jobs.JobChangeAdapter;
-
-/**
- * Utility for testing if a job for a specific family has been scheduled.
- * <p>
- * Must be created before the test code is run, and then tested afterwards using
- * {@link #assertScheduled(String)}.
- * <p>
- * This is more robust than using {@link IJobManager#find(Object)} after running
- * the test code because it registers a listener and is not prone to the job
- * being done already at the time of calling <code>find</code>.
- */
-public class JobSchedulingAssert extends JobChangeAdapter {
-
-	private final Object jobFamily;
-
-	private boolean scheduled = false;
-
-	public static JobSchedulingAssert forFamily(Object jobFamily) {
-		return new JobSchedulingAssert(jobFamily);
-	}
-
-	private JobSchedulingAssert(Object jobFamily) {
-		this.jobFamily = jobFamily;
-		Job.getJobManager().addJobChangeListener(this);
-	}
-
-	@Override
-	public void scheduled(IJobChangeEvent event) {
-		if (event.getJob().belongsTo(jobFamily))
-			scheduled = true;
-	}
-
-	/**
-	 * Assert that the job has indeed been scheduled.
-	 *
-	 * @param messageForFailure
-	 *            message for when the assertion should fail
-	 */
-	public void assertScheduled(String messageForFailure) {
-		Job.getJobManager().removeJobChangeListener(this);
-		assertTrue(messageForFailure, scheduled);
-	}
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/LinkedResourcesTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/LinkedResourcesTest.java
deleted file mode 100644
index d17453e..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/LinkedResourcesTest.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2013, François Rey <eclipse.org_@_francois_._rey_._name>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *    François Rey - First implementation as part of handling linked resources
- *******************************************************************************/
-package org.eclipse.egit.core.test;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import java.io.File;
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IWorkspaceRoot;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.ContainerTreeIterator;
-import org.eclipse.egit.core.GitProvider;
-import org.eclipse.egit.core.IteratorService;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.treewalk.WorkingTreeIterator;
-import org.eclipse.team.core.RepositoryProvider;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class LinkedResourcesTest {
-
-	TestUtils testUtils;
-
-	File project1Dir;
-
-	File project2Dir;
-
-	TestRepository repository1;
-
-	TestRepository repository2;
-
-	String project1Name = "project1";
-
-	String project2Name = "project2";
-
-	IProject project1;
-
-	IProject project2;
-
-	GitResourceDeltaTestHelper resourceDeltaTestHelper1;
-
-	GitResourceDeltaTestHelper resourceDeltaTestHelper2;
-
-	@Before
-	public void setUp() throws Exception {
-		testUtils = new TestUtils();
-		// Create first repo and project
-		project1 = testUtils.createProjectInLocalFileSystem(project1Name);
-		project1Dir = project1.getRawLocation().toFile();
-		repository1 = new TestRepository(new File(project1Dir,
-				Constants.DOT_GIT));
-		testUtils.addFileToProject(project1,
-				"project1folder1/project1folder1file1.txt", "Hello world");
-		repository1.connect(project1);
-		repository1.trackAllFiles(project1);
-		repository1.commit("Initial commit");
-		// Create 2nd repo and project
-		project2 = testUtils.createProjectInLocalFileSystem(project2Name);
-		project2Dir = project2.getRawLocation().toFile();
-		repository2 = new TestRepository(new File(project2Dir,
-				Constants.DOT_GIT));
-		testUtils.addFileToProject(project2,
-				"project2folder1/project2folder1file1.txt", "Hello world");
-		repository2.connect(project2);
-		repository2.trackAllFiles(project2);
-		repository2.commit("Initial commit");
-		// Set up git delta listener
-		resourceDeltaTestHelper1 = new GitResourceDeltaTestHelper(
-				repository1.getRepository());
-		resourceDeltaTestHelper1.setUp();
-		resourceDeltaTestHelper2 = new GitResourceDeltaTestHelper(
-				repository2.getRepository());
-		resourceDeltaTestHelper2.setUp();
-	}
-
-	@After
-	public void tearDown() throws Exception {
-		if (resourceDeltaTestHelper1 != null)
-			resourceDeltaTestHelper1.tearDown();
-		if (resourceDeltaTestHelper2 != null)
-			resourceDeltaTestHelper2.tearDown();
-		project1.delete(true, null);
-		project2.delete(true, null);
-		project1 = null;
-		project2 = null;
-		repository1.dispose();
-		repository2.dispose();
-		repository1 = null;
-		repository2 = null;
-		testUtils.deleteTempDirs();
-		testUtils = null;
-		Activator.getDefault().getRepositoryCache().clear();
-	}
-
-	@Test
-	public void testGitProviderCanHandleLinkedResources() throws Exception {
-		GitProvider provider = (GitProvider) RepositoryProvider
-				.getProvider(project1);
-		assertTrue(provider.canHandleLinkedResourceURI());
-	}
-
-	@Test
-	public void testLinkedResourcesIgnoredByGitResourceDeltaVisitor()
-			throws Exception {
-		// Create linked folder in project1 that points to project2
-		IFolder folder = project1.getFolder("link2project2");
-		folder.createLink(project2.getLocation(),
-				IResource.ALLOW_MISSING_LOCAL, null);
-		// Create linked file in project1 that points to a file in project2
-		IFile file = project1.getFile("link2project2folder1file1.txt");
-		file.createLink(
-				project2.getFile("project2folder1/project2folder1file1.txt")
-						.getLocation(), IResource.ALLOW_MISSING_LOCAL, null);
-		// Add file to project2
-		testUtils.addFileToProject(project2,
-				"project2folder1/project2folder1file2.txt", "Hello world");
-		// Links are written to the .project file
-		resourceDeltaTestHelper1
-				.assertChangedResources(new String[] { "/project1/.project" });
-		// Changes to linked resources are reported against their repository
-		resourceDeltaTestHelper2.assertChangedResources(new String[] {
-						"/project1/link2project2/project2folder1",
-						"/project1/link2project2/project2folder1/project2folder1file2.txt",
-						"/project1/link2project2/.project",
-						"/project1/link2project2/project2folder1/project2folder1file1.txt",
-						"/project1/link2project2",
-				"/project2/project2folder1/project2folder1file2.txt" });
-	}
-
-	@Test
-	public void testLinkedResourcesIgnoredByIteratorService() throws Exception {
-		// Create linked folder in project1 that points to project2
-		IFolder folder = project1.getFolder("link2project2");
-		folder.createLink(project2.getLocation(),
-				IResource.ALLOW_MISSING_LOCAL, null);
-		// Linked resources are ignored when searching the container of a folder
-		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
-		IContainer container = IteratorService.findContainer(root, folder
-				.getRawLocation().makeAbsolute().toFile());
-		assertTrue(project2.equals(container));
-		// Also test when the only project left is the one linking to the folder
-		repository2.disconnect(project2);
-		container = IteratorService.findContainer(root, folder.getRawLocation()
-				.makeAbsolute().toFile());
-		assertNull(container);
-	}
-
-	@Test
-	public void testLinkedResourcesIgnoredByContainerTreeIterator()
-			throws Exception {
-		// Create linked folder in project1 that points to project2
-		IFolder folder = project1.getFolder("link2project2");
-		folder.createLink(project2.getLocation(),
-				IResource.ALLOW_MISSING_LOCAL, null);
-		// Create linked file in project1 that points to a file in project2
-		IFile file = project1.getFile("link2project2folder1file1.txt");
-		file.createLink(
-				project2.getFile("project2folder1/project2folder1file1.txt")
-						.getLocation(), IResource.ALLOW_MISSING_LOCAL, null);
-		// Test iterator
-		WorkingTreeIterator iterator = IteratorService
-				.createInitialIterator(repository1.repository);
-		assertTrue(iterator instanceof ContainerTreeIterator);
-		while (!iterator.eof()) {
-			assertFalse(iterator.getEntryPathString().startsWith("link2"));
-			iterator.next(1);
-		}
-	}
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/ProjectReferenceTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/ProjectReferenceTest.java
deleted file mode 100644
index ed2683e..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/ProjectReferenceTest.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2011, Manuel Doninger <manuel.doninger@googlemail.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- *******************************************************************************/
-package org.eclipse.egit.core.test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-import java.net.URISyntaxException;
-
-import org.eclipse.egit.core.ProjectReference;
-import org.junit.Before;
-import org.junit.Test;
-
-public class ProjectReferenceTest {
-
-	private String version = "1.0";
-	private String url = "git://egit.eclipse.org/egit.git";
-	private String branch = "master";
-	private String project = "org.eclipse.egit.core";
-	private ProjectReference projectReference;
-
-	@Before
-	public void createProjectReferenceFromString() throws IllegalArgumentException, URISyntaxException {
-		String reference = version + "," + url + "," + branch + "," + project;
-		projectReference = new ProjectReference(reference);
-		assertNotNull(projectReference);
-	}
-
-	@Test
-	public void checkUrl() {
-		assertEquals(url, projectReference.getRepository().toString());
-	}
-
-	@Test
-	public void checkBranch() {
-		assertEquals(branch, projectReference.getBranch());
-	}
-
-	@Test
-	public void checkProject() {
-		assertEquals(project, projectReference.getProjectDir());
-	}
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/RepositoryCacheTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/RepositoryCacheTest.java
deleted file mode 100644
index c392eca..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/RepositoryCacheTest.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2012 Red Hat, Inc. Distributed under license by Red Hat, Inc.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *    Andre Dietisheim - initial API and implementation
- *******************************************************************************/
-package org.eclipse.egit.core.test;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.isIn;
-import static org.hamcrest.core.IsNot.not;
-
-import java.io.IOException;
-
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.RepositoryCache;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.util.FileUtils;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class RepositoryCacheTest extends GitTestCase {
-
-	private TestRepository testRepository;
-	private Repository repository;
-	private RepositoryCache cache;
-
-	@Before
-	public void setUp() throws Exception {
-		super.setUp();
-		this.testRepository = new TestRepository(gitDir);
-		this.repository = testRepository.getRepository();
-		this.cache = Activator.getDefault().getRepositoryCache();
-	}
-
-	@After
-	public void tearDown() throws Exception {
-		testRepository.dispose();
-		repository = null;
-		super.tearDown();
-	}
-
-	@Test
-	public void shouldNotContainDeletedRepository() throws IOException {
-		cache.lookupRepository(repository.getDirectory());
-		assertThat(repository, isIn(cache.getAllRepositories()));
-		FileUtils.delete(repository.getDirectory(), FileUtils.RECURSIVE);
-		assertThat(repository, not(isIn(cache.getAllRepositories())));
-	}
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/RevUtilsTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/RevUtilsTest.java
deleted file mode 100644
index 6fd7f20..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/RevUtilsTest.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2012, Robin Stocker <robin@nibor.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.test;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import java.io.IOException;
-import java.util.Collection;
-
-import org.eclipse.egit.core.RevUtils;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.revwalk.RevCommit;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class RevUtilsTest extends GitTestCase {
-
-	private TestRepository testRepository;
-	private Repository repository;
-
-	@Before
-	public void setUp() throws Exception {
-		super.setUp();
-		testRepository = new TestRepository(gitDir);
-		repository = testRepository.getRepository();
-	}
-
-	@After
-	public void tearDown() throws Exception {
-		testRepository.dispose();
-		repository = null;
-		super.tearDown();
-	}
-
-	@Test
-	public void isContainedInAnyRef() throws Exception {
-		RevCommit first = testRepository.createInitialCommit("First commit");
-		testRepository.createBranch("refs/heads/master", "refs/heads/other");
-		assertFalse(isContainedInAnyRemoteRef(first));
-
-		testRepository.createBranch("refs/heads/master", "refs/remotes/origin/a");
-		assertTrue(isContainedInAnyRemoteRef(first));
-
-		RevCommit second = testRepository.commit("Second commit");
-		assertFalse(isContainedInAnyRemoteRef(second));
-
-		testRepository.createBranch("refs/heads/master", "refs/remotes/origin/b");
-		assertTrue(isContainedInAnyRemoteRef(second));
-
-		RevCommit third = testRepository.commit("Third commit");
-		testRepository.commit("Fourth commit");
-		testRepository.createBranch("refs/heads/master", "refs/remotes/origin/c");
-		assertTrue(isContainedInAnyRemoteRef(third));
-	}
-
-	private boolean isContainedInAnyRemoteRef(RevCommit commit) throws IOException {
-		Collection<Ref> remoteRefs = repository.getRefDatabase().getRefs(Constants.R_REMOTES).values();
-		return RevUtils.isContainedInAnyRef(repository, commit, remoteRefs);
-	}
-
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/TestProject.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/TestProject.java
deleted file mode 100644
index 31e759e..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/TestProject.java
+++ /dev/null
@@ -1,294 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2007, Robin Rosenberg <robin.rosenberg@dewire.com>
- * Copyright (C) 2006, Shawn O. Pearce <spearce@spearce.org>
- * Copyright (C) 2012, Robin Stocker <robin@nibor.org>
- * Copyright (C) 2013, Matthias Sohn <matthias.sohn@sap.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.test;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URI;
-import java.net.URL;
-
-import org.eclipse.core.filesystem.URIUtil;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IProjectDescription;
-import org.eclipse.core.resources.IWorkspaceRoot;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.core.runtime.Platform;
-import org.eclipse.jdt.core.IClasspathEntry;
-import org.eclipse.jdt.core.ICompilationUnit;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.IPackageFragment;
-import org.eclipse.jdt.core.IPackageFragmentRoot;
-import org.eclipse.jdt.core.IType;
-import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.launching.JavaRuntime;
-import org.eclipse.jgit.util.FileUtils;
-import org.osgi.framework.Bundle;
-
-public class TestProject {
-	public IProject project;
-
-	public IJavaProject javaProject;
-
-	private IPackageFragmentRoot sourceFolder;
-	private String location;
-	private TestUtils testUtils = new TestUtils();
-
-	private final File workspaceSupplement;
-
-	private IFolder binFolder;
-
-	/**
-	 * @throws CoreException
-	 *             If project already exists
-	 */
-	public TestProject() throws CoreException {
-		this(false);
-	}
-
-	public TestProject(boolean remove) throws CoreException {
-		this(remove, "Project-1");
-	}
-
-	/**
-	 * @param remove
-	 *            should project be removed if already exists
-	 * @param path
-	 * @throws CoreException
-	 */
-	public TestProject(final boolean remove, String path) throws CoreException {
-		this(remove, path, true, null);
-	}
-
-	/**
-	 * @param remove
-	 *            should project be removed if already exists
-	 * @param path
-	 * @param insidews set false to create in temp
-	 * @param workspaceSupplement
-	 * @throws CoreException
-	 */
-	public TestProject(final boolean remove, String path, boolean insidews, File workspaceSupplement) throws CoreException {
-		this.workspaceSupplement = workspaceSupplement;
-		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
-		IProjectDescription description = createDescription(path, insidews,
-				root, workspaceSupplement);
-		project = root.getProject(description.getName());
-		if (remove)
-			project.delete(true, null);
-		IPath locationBefore = description.getLocation();
-		if (locationBefore == null)
-			locationBefore = root.getRawLocation().append(path);
-		location = locationBefore.toOSString();
-		project.create(description, null);
-		project.open(null);
-		javaProject = JavaCore.create(project);
-		binFolder = createBinFolder();
-		setJavaNature();
-		javaProject.setRawClasspath(new IClasspathEntry[0], null);
-		createOutputFolder(binFolder);
-		addSystemLibraries();
-	}
-
-	public void setBinFolderDerived() throws CoreException {
-		binFolder.setDerived(true, null);
-	}
-
-	public File getWorkspaceSupplement() {
-		return workspaceSupplement;
-	}
-
-	private IProjectDescription createDescription(String path,
-			boolean insidews, IWorkspaceRoot root, File workspaceSupplement) {
-		Path ppath = new Path(path);
-		String projectName = ppath.lastSegment();
-		URI locationURI;
-		URI top;
-		if (insidews) {
-			top = root.getRawLocationURI();
-		} else {
-			top = URIUtil.toURI(workspaceSupplement.getAbsolutePath());
-		}
-		if (!insidews || !ppath.lastSegment().equals(path)) {
-			locationURI = URIUtil.toURI(URIUtil.toPath(top).append(path));
-		} else
-			locationURI = null;
-		IProjectDescription description = ResourcesPlugin.getWorkspace()
-				.newProjectDescription(projectName);
-
-		description.setName(projectName);
-		description.setLocationURI(locationURI);
-		return description;
-	}
-
-	public IProject getProject() {
-		return project;
-	}
-
-	public IJavaProject getJavaProject() {
-		return javaProject;
-	}
-
-	public void addJar(String plugin, String jar) throws JavaModelException {
-		Path result = findFileInPlugin(plugin, jar);
-		IClasspathEntry[] oldEntries = javaProject.getRawClasspath();
-		IClasspathEntry[] newEntries = new IClasspathEntry[oldEntries.length + 1];
-		System.arraycopy(oldEntries, 0, newEntries, 0, oldEntries.length);
-		newEntries[oldEntries.length] = JavaCore.newLibraryEntry(result, null,
-				null);
-		javaProject.setRawClasspath(newEntries, null);
-	}
-
-	public IPackageFragment createPackage(String name) throws CoreException {
-		if (sourceFolder == null)
-			sourceFolder = createSourceFolder();
-		return sourceFolder.createPackageFragment(name, false, null);
-	}
-
-	public IType createType(IPackageFragment pack, String cuName, String source)
-			throws JavaModelException {
-		StringBuilder buf = new StringBuilder();
-		buf.append("package " + pack.getElementName() + ";\n");
-		buf.append("\n");
-		buf.append(source);
-		ICompilationUnit cu = pack.createCompilationUnit(cuName,
-				buf.toString(), false, null);
-		return cu.getTypes()[0];
-	}
-
-	public IFile createFile(String name, byte[] content) throws Exception {
-		IFile file = project.getFile(name);
-		InputStream inputStream = new ByteArrayInputStream(content);
-		file.create(inputStream, true, null);
-
-		return file;
-	}
-
-	public IFolder createFolder(String name) throws Exception {
-		IFolder folder = project.getFolder(name);
-		folder.create(true, true, null);
-		return folder;
-	}
-
-	public IFolder createFolderWithKeep(String name) throws Exception {
-		IFolder folder = createFolder(name);
-
-		IFile keep = project.getFile(name + "/keep");
-		keep.create(new ByteArrayInputStream(new byte[] {0}), true, null);
-
-		return folder;
-	}
-
-	public void dispose() throws CoreException, IOException {
-		waitForIndexer();
-		if (project.exists())
-			project.delete(true, true, null);
-		else {
-			File f = new File(location);
-			if (f.exists())
-				FileUtils.delete(f, FileUtils.RECURSIVE | FileUtils.RETRY);
-		}
-	}
-
-	private IFolder createBinFolder() throws CoreException {
-		IFolder binFolder = project.getFolder("bin");
-		binFolder.create(false, true, null);
-		return binFolder;
-	}
-
-	private void setJavaNature() throws CoreException {
-		IProjectDescription description = project.getDescription();
-		description.setNatureIds(new String[] { JavaCore.NATURE_ID });
-		project.setDescription(description, null);
-	}
-
-	private void createOutputFolder(IFolder binFolder)
-			throws JavaModelException {
-		IPath outputLocation = binFolder.getFullPath();
-		javaProject.setOutputLocation(outputLocation, null);
-	}
-
-	public IPackageFragmentRoot createSourceFolder() throws CoreException {
-		IFolder folder = project.getFolder("src");
-		folder.create(false, true, null);
-		IPackageFragmentRoot root = javaProject.getPackageFragmentRoot(folder);
-		IClasspathEntry[] oldEntries = javaProject.getRawClasspath();
-		IClasspathEntry[] newEntries = new IClasspathEntry[oldEntries.length + 1];
-		System.arraycopy(oldEntries, 0, newEntries, 0, oldEntries.length);
-		newEntries[oldEntries.length] = JavaCore.newSourceEntry(root.getPath());
-		javaProject.setRawClasspath(newEntries, null);
-		return root;
-	}
-
-	private void addSystemLibraries() throws JavaModelException {
-		IClasspathEntry[] oldEntries = javaProject.getRawClasspath();
-		IClasspathEntry[] newEntries = new IClasspathEntry[oldEntries.length + 1];
-		System.arraycopy(oldEntries, 0, newEntries, 0, oldEntries.length);
-		newEntries[oldEntries.length] = JavaRuntime
-				.getDefaultJREContainerEntry();
-		javaProject.setRawClasspath(newEntries, null);
-	}
-
-	private Path findFileInPlugin(String plugin, String file) {
-		Bundle bundle = Platform.getBundle(plugin);
-		URL resource = bundle.getResource(file);
-		return new Path(resource.getPath());
-	}
-
-	public void waitForIndexer() {
-		//                new SearchEngine().searchAllTypeNames(ResourcesPlugin.getWorkspace(),
-		//                                null, null, IJavaSearchConstants.EXACT_MATCH,
-		//                                IJavaSearchConstants.CASE_SENSITIVE,
-		//                                IJavaSearchConstants.CLASS, SearchEngine
-		//                                                .createJavaSearchScope(new IJavaElement[0]),
-		//                                new ITypeNameRequestor() {
-		//                                        public void acceptClass(char[] packageName,
-		//                                                        char[] simpleTypeName, char[][] enclosingTypeNames,
-		//                                                        String path) {
-		//                                        }
-		//                                        public void acceptInterface(char[] packageName,
-		//                                                        char[] simpleTypeName, char[][] enclosingTypeNames,
-		//                                                        String path) {
-		//                                        }
-		//                                }, IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH, null);
-	}
-
-	public String getFileContent(String filepath) throws Exception {
-		IFile file = project.getFile(filepath);
-		InputStream stream = file.getContents();
-		return testUtils.slurpAndClose(stream);
-	}
-	/**
-	 * @return Returns the sourceFolder.
-	 */
-	public IPackageFragmentRoot getSourceFolder() {
-		return sourceFolder;
-	}
-
-	/**
-	 * @param sourceFolder The sourceFolder to set.
-	 */
-	public void setSourceFolder(IPackageFragmentRoot sourceFolder) {
-		this.sourceFolder = sourceFolder;
-	}
-
-	public String getLocation() {
-		return location;
-	}
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/TestRepository.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/TestRepository.java
deleted file mode 100644
index 986acb1..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/TestRepository.java
+++ /dev/null
@@ -1,545 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2011, Mathias Kinzler <mathias.kinzler@sap.com>
- * Copyright (C) 2010, Jens Baumgart <jens.baumgart@sap.com>
- * Copyright (C) 2012, Robin Stocker <robin@nibor.org>
- * Copyright (C) 2012, François Rey <eclipse.org_@_francois_._rey_._name>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.test;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.net.URISyntaxException;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.regex.Pattern;
-
-import org.eclipse.core.filesystem.EFS;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IResourceVisitor;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.op.BranchOperation;
-import org.eclipse.egit.core.op.ConnectProviderOperation;
-import org.eclipse.egit.core.op.DisconnectProviderOperation;
-import org.eclipse.jgit.api.CommitCommand;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.api.errors.ConcurrentRefUpdateException;
-import org.eclipse.jgit.api.errors.GitAPIException;
-import org.eclipse.jgit.api.errors.JGitInternalException;
-import org.eclipse.jgit.api.errors.NoFilepatternException;
-import org.eclipse.jgit.api.errors.NoHeadException;
-import org.eclipse.jgit.api.errors.NoMessageException;
-import org.eclipse.jgit.api.errors.WrongRepositoryStateException;
-import org.eclipse.jgit.dircache.DirCache;
-import org.eclipse.jgit.dircache.DirCacheEntry;
-import org.eclipse.jgit.errors.UnmergedPathException;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.lib.RefUpdate;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.jgit.revwalk.RevWalk;
-import org.eclipse.jgit.internal.storage.file.FileRepository;
-import org.eclipse.jgit.transport.URIish;
-import org.eclipse.jgit.treewalk.TreeWalk;
-import org.eclipse.jgit.util.FileUtils;
-
-/**
- * Helper class for creating and filling a test repository
- *
- */
-public class TestRepository {
-
-	Repository repository;
-
-	String workdirPrefix;
-
-	/**
-	 * Creates a new test repository
-	 *
-	 * @param gitDir
-	 * @throws IOException
-	 */
-	public TestRepository(File gitDir) throws IOException {
-		FileRepository tmpRepository = new FileRepository(gitDir);
-		tmpRepository.create();
-		tmpRepository.close();
-		// use repository instance from RepositoryCache!
-		repository = Activator.getDefault().getRepositoryCache().lookupRepository(gitDir);
-		try {
-			workdirPrefix = repository.getWorkTree().getCanonicalPath();
-		} catch (IOException err) {
-			workdirPrefix = repository.getWorkTree().getAbsolutePath();
-		}
-		workdirPrefix = workdirPrefix.replace('\\', '/');
-		if (!workdirPrefix.endsWith("/")) //$NON-NLS-1$
-			workdirPrefix += "/"; //$NON-NLS-1$
-	}
-
-	/**
-	 * Creates a test repository from an existing Repository
-	 *
-	 * @param repository
-	 * @throws IOException
-	 */
-	public TestRepository(Repository repository) throws IOException {
-		this.repository = repository;
-		try {
-			workdirPrefix = repository.getWorkTree().getCanonicalPath();
-		} catch (IOException err) {
-			workdirPrefix = repository.getWorkTree().getAbsolutePath();
-		}
-		workdirPrefix = workdirPrefix.replace('\\', '/');
-		if (!workdirPrefix.endsWith("/")) //$NON-NLS-1$
-			workdirPrefix += "/"; //$NON-NLS-1$
-	}
-
-	/**
-	 * @return the wrapped repository
-	 */
-	public Repository getRepository() {
-		return repository;
-	}
-
-	/**
-	 * create an initial commit containing a file "dummy" in the
-	 *
-	 * @param message
-	 *            commit message
-	 * @return commit object
-	 * @throws IOException
-	 * @throws JGitInternalException
-	 * @throws GitAPIException
-	 * @throws NoFilepatternException
-	 */
-	public RevCommit createInitialCommit(String message) throws IOException,
-			JGitInternalException, NoFilepatternException, GitAPIException {
-		String repoPath = repository.getWorkTree().getAbsolutePath();
-		File file = new File(repoPath, "dummy");
-		if (!file.exists())
-			FileUtils.createNewFile(file);
-		track(file);
-		return commit(message);
-	}
-
-	/**
-	 * Create a file or get an existing one
-	 *
-	 * @param project
-	 *            instance of project inside with file will be created
-	 * @param name
-	 *            name of file
-	 * @return nearly created file
-	 * @throws IOException
-	 */
-	public File createFile(IProject project, String name) throws IOException {
-		String path = project.getLocation().append(name).toOSString();
-		int lastSeparator = path.lastIndexOf(File.separator);
-		FileUtils.mkdirs(new File(path.substring(0, lastSeparator)), true);
-
-		File file = new File(path);
-		if (!file.exists())
-			FileUtils.createNewFile(file);
-
-		return file;
-	}
-
-	/**
-	 * Track, add to index and finally commit given file
-	 *
-	 * @param project
-	 * @param file
-	 * @param commitMessage
-	 * @return commit object
-	 * @throws Exception
-	 */
-	public RevCommit addAndCommit(IProject project, File file, String commitMessage)
-			throws Exception {
-		track(file);
-		addToIndex(project, file);
-
-		return commit(commitMessage);
-	}
-
-	/**
-	 * Appends file content to given file, then track, add to index and finally
-	 * commit it.
-	 *
-	 * @param project
-	 * @param file
-	 * @param content
-	 * @param commitMessage
-	 * @return commit object
-	 * @throws Exception
-	 */
-	public RevCommit appendContentAndCommit(IProject project, File file,
-			byte[] content, String commitMessage) throws Exception {
-		return appendContentAndCommit(project, file, new String(content),
-				commitMessage);
-	}
-
-	/**
-	 * Appends file content to given file, then track, add to index and finally
-	 * commit it.
-	 *
-	 * @param project
-	 * @param file
-	 * @param content
-	 * @param commitMessage
-	 * @return commit object
-	 * @throws Exception
-	 */
-	public RevCommit appendContentAndCommit(IProject project, File file,
-			String content, String commitMessage) throws Exception {
-		appendFileContent(file, content);
-		track(file);
-		addToIndex(project, file);
-
-		return commit(commitMessage);
-	}
-
-	/**
-	 * Commits the current index
-	 *
-	 * @param message
-	 *            commit message
-	 * @return commit object
-	 *
-	 * @throws NoHeadException
-	 * @throws NoMessageException
-	 * @throws UnmergedPathException
-	 * @throws ConcurrentRefUpdateException
-	 * @throws JGitInternalException
-	 * @throws GitAPIException
-	 * @throws WrongRepositoryStateException
-	 */
-	public RevCommit commit(String message) throws NoHeadException,
-			NoMessageException, UnmergedPathException,
-			ConcurrentRefUpdateException, JGitInternalException,
-			WrongRepositoryStateException, GitAPIException {
-		Git git = new Git(repository);
-		CommitCommand commitCommand = git.commit();
-		commitCommand.setAuthor("J. Git", "j.git@egit.org");
-		commitCommand.setCommitter(commitCommand.getAuthor());
-		commitCommand.setMessage(message);
-		return commitCommand.call();
-	}
-
-	/**
-	 * Adds file to version control
-	 *
-	 * @param file
-	 * @throws IOException
-	 * @throws GitAPIException
-	 * @throws NoFilepatternException
-	 */
-	public void track(File file) throws IOException, NoFilepatternException, GitAPIException {
-		String repoPath = getRepoRelativePath(new Path(file.getPath())
-				.toString());
-		new Git(repository).add().addFilepattern(repoPath).call();
-	}
-
-	/**
-	 * Adds all project files to version control
-	 *
-	 * @param project
-	 * @throws CoreException
-	 */
-	public void trackAllFiles(IProject project) throws CoreException {
-		project.accept(new IResourceVisitor() {
-
-			public boolean visit(IResource resource) throws CoreException {
-				if (resource instanceof IFile) {
-					try {
-						track(EFS.getStore(resource.getLocationURI())
-										.toLocalFile(0, null));
-					} catch (Exception e) {
-						throw new CoreException(Activator.error(e.getMessage(),
-								e));
-					}
-				}
-				return true;
-			}
-		});
-	}
-
-	/**
-	 * Removes file from version control
-	 *
-	 * @param file
-	 * @throws IOException
-	 */
-	public void untrack(File file) throws IOException {
-		String repoPath = getRepoRelativePath(new Path(file.getPath())
-				.toString());
-		try {
-			new Git(repository).rm().addFilepattern(repoPath).call();
-		} catch (GitAPIException e) {
-			throw new IOException(e.getMessage());
-		}
-	}
-
-	/**
-	 * Creates a new branch and immediately checkout it.
-	 *
-	 * @param refName
-	 *            starting point for the new branch
-	 * @param newRefName
-	 * @throws Exception
-	 */
-	public void createAndCheckoutBranch(String refName, String newRefName) throws Exception {
-		createBranch(refName, newRefName);
-		checkoutBranch(newRefName);
-	}
-
-	/**
-	 * Creates a new branch
-	 *
-	 * @param refName
-	 *            starting point for the new branch
-	 * @param newRefName
-	 * @throws IOException
-	 */
-	public void createBranch(String refName, String newRefName)
-			throws IOException {
-		RefUpdate updateRef;
-		updateRef = repository.updateRef(newRefName);
-		Ref startRef = repository.getRef(refName);
-		ObjectId startAt = repository.resolve(refName);
-		String startBranch;
-		if (startRef != null)
-			startBranch = refName;
-		else
-			startBranch = startAt.name();
-		startBranch = Repository.shortenRefName(startBranch);
-		updateRef.setNewObjectId(startAt);
-		updateRef
-				.setRefLogMessage("branch: Created from " + startBranch, false); //$NON-NLS-1$
-		updateRef.update();
-	}
-
-	/**
-	 * Checkouts branch
-	 *
-	 * @param refName
-	 *            full name of branch
-	 * @throws CoreException
-	 */
-	public void checkoutBranch(String refName) throws CoreException {
-		new BranchOperation(repository, refName).execute(null);
-	}
-
-	/**
-	 * Adds the given file to the index
-	 *
-	 * @param project
-	 * @param file
-	 * @throws Exception
-	 */
-	public void addToIndex(IProject project, File file) throws Exception {
-		IFile iFile = getIFile(project, file);
-		addToIndex(iFile);
-	}
-
-
-	/**
-	 * Adds the given resource to the index
-	 *
-	 * @param resource
-	 * @throws CoreException
-	 * @throws IOException
-	 * @throws GitAPIException
-	 * @throws NoFilepatternException
-	 */
-	public void addToIndex(IResource resource) throws CoreException, IOException, NoFilepatternException, GitAPIException {
-		String repoPath = getRepoRelativePath(resource.getLocation().toOSString());
-		new Git(repository).add().addFilepattern(repoPath).call();
-	}
-
-	/**
-	 * Appends content to end of given file.
-	 *
-	 * @param file
-	 * @param content
-	 * @throws IOException
-	 */
-	public void appendFileContent(File file, byte[] content) throws IOException {
-		appendFileContent(file, new String(content), true);
-	}
-
-	/**
-	 * Appends content to end of given file.
-	 *
-	 * @param file
-	 * @param content
-	 * @throws IOException
-	 */
-	public void appendFileContent(File file, String content) throws IOException {
-		appendFileContent(file, content, true);
-	}
-
-	/**
-	 * Appends content to given file.
-	 *
-	 * @param file
-	 * @param content
-	 * @param append
-	 *            if true, then bytes will be written to the end of the file
-	 *            rather than the beginning
-	 * @throws IOException
-	 */
-	public void appendFileContent(File file, byte[] content, boolean append)
-			throws IOException {
-		appendFileContent(file, new String(content), append);
-	}
-
-	/**
-	 * Appends content to given file.
-	 *
-	 * @param file
-	 * @param content
-	 * @param append
-	 *            if true, then bytes will be written to the end of the file
-	 *            rather than the beginning
-	 * @throws IOException
-	 */
-	public void appendFileContent(File file, String content, boolean append)
-			throws IOException {
-		FileWriter fw = null;
-		try {
-			fw = new FileWriter(file, append);
-			fw.append(content);
-		} finally {
-			if (fw != null)
-				fw.close();
-		}
-	}
-
-	/**
-	 * Checks if a file with the given path exists in the HEAD tree
-	 *
-	 * @param path
-	 * @return true if the file exists
-	 * @throws IOException
-	 */
-	public boolean inHead(String path) throws IOException {
-		ObjectId headId = repository.resolve(Constants.HEAD);
-		RevWalk rw = new RevWalk(repository);
-		TreeWalk tw = null;
-		try {
-			tw = TreeWalk.forPath(repository, path, rw.parseTree(headId));
-			return tw != null;
-		} finally {
-			rw.release();
-			rw.dispose();
-			if (tw != null)
-				tw.release();
-		}
-	}
-
-	public boolean inIndex(String absolutePath) throws IOException {
-		return getDirCacheEntry(absolutePath) != null;
-	}
-
-	public boolean removedFromIndex(String absolutePath) throws IOException {
-		DirCacheEntry dc = getDirCacheEntry(absolutePath);
-		if (dc == null)
-			return true;
-
-		Ref ref = repository.getRef(Constants.HEAD);
-		RevCommit c = new RevWalk(repository).parseCommit(ref.getObjectId());
-		TreeWalk tw = TreeWalk.forPath(repository, getRepoRelativePath(absolutePath), c.getTree());
-
-		return tw == null || dc.getObjectId().equals(tw.getObjectId(0));
-	}
-
-	public long lastModifiedInIndex(String path) throws IOException {
-		String repoPath = getRepoRelativePath(path);
-		DirCache dc = DirCache.read(repository.getIndexFile(), repository.getFS());
-
-		return dc.getEntry(repoPath).getLastModified();
-	}
-
-	public int getDirCacheEntryLength(String path) throws IOException {
-		String repoPath = getRepoRelativePath(path);
-		DirCache dc = DirCache.read(repository.getIndexFile(), repository.getFS());
-
-		return dc.getEntry(repoPath).getLength();
-	}
-
-	public String getRepoRelativePath(String path) {
-		final int pfxLen = workdirPrefix.length();
-		final int pLen = path.length();
-		if (pLen > pfxLen)
-			return path.substring(pfxLen);
-		else if (path.length() == pfxLen - 1)
-			return ""; //$NON-NLS-1$
-		return null;
-	}
-
-	public IFile getIFile(IProject project, File file) throws CoreException {
-		String relativePath = getRepoRelativePath(file.getAbsolutePath());
-
-		String quotedProjectName = Pattern.quote(project.getName());
-		relativePath = relativePath.replaceFirst(quotedProjectName, "");
-
-		IFile iFile = project.getFile(relativePath);
-		iFile.refreshLocal(0, null);
-
-		return iFile;
-	}
-
-	public void dispose() {
-		if (repository != null) {
-			repository.close();
-			repository = null;
-		}
-	}
-
-	/**
-	 * Connect a project to this repository
-	 *
-	 * @param project
-	 * @throws CoreException
-	 */
-	public void connect(IProject project) throws CoreException {
-		ConnectProviderOperation op = new ConnectProviderOperation(project,
-				this.getRepository().getDirectory());
-		op.execute(null);
-	}
-
-	/**
-	 * Disconnects provider from project
-	 *
-	 * @param project
-	 * @throws CoreException
-	 */
-	public void disconnect(IProject project) throws CoreException {
-		Collection<IProject> projects = Collections.singleton(project
-				.getProject());
-		DisconnectProviderOperation disconnect = new DisconnectProviderOperation(
-				projects);
-		disconnect.execute(null);
-	}
-
-	public URIish getUri() throws URISyntaxException {
-		return new URIish("file:///" + repository.getDirectory().toString());
-	}
-
-	private DirCacheEntry getDirCacheEntry(String path) throws IOException {
-		String repoPath = getRepoRelativePath(path);
-		DirCache dc = DirCache.read(repository.getIndexFile(), repository.getFS());
-
-		return dc.getEntry(repoPath);
-	}
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/TestUtils.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/TestUtils.java
deleted file mode 100644
index a0f34b9..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/TestUtils.java
+++ /dev/null
@@ -1,286 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2007, Robin Rosenberg <robin.rosenberg@dewire.com>
- * Copyright (C) 2010, Jens Baumgart <jens.baumgart@sap.com>
- * Copyright (C) 2010, Mathias Kinzler <mathias.kinzler@sap.com>
- * Copyright (C) 2012, François Rey <eclipse.org_@_francois_._rey_._name>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.test;
-
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IProjectDescription;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.treewalk.TreeWalk;
-import org.eclipse.jgit.util.FS;
-import org.eclipse.jgit.util.FileUtils;
-
-public class TestUtils {
-
-	public final static String AUTHOR = "The Author <The.author@some.com>";
-
-	public final static String COMMITTER = "The Commiter <The.committer@some.com>";
-
-	/**
-	 * Return the base directory in which temporary directories are created.
-	 * Current implementation returns a "temporary" folder in the user home.
-	 *
-	 * @return a "temporary" folder in the user home that may not exist.
-	 * @throws IOException
-	 */
-	public File getBaseTempDir() throws IOException {
-		File userHome = FS.DETECTED.userHome();
-		File rootDir = new File(userHome, "EGitCoreTestTempDir");
-		return rootDir;
-	}
-
-	/**
-	 * Create a "temporary" directory
-	 *
-	 * @param name
-	 *            the name of the directory
-	 * @return a directory as child of a "temporary" folder in the user home
-	 *         directory; may or may not exist
-	 * @throws IOException
-	 */
-	public File createTempDir(String name) throws IOException {
-		File result = new File(getBaseTempDir(), name);
-		if (result.exists())
-			FileUtils.delete(result, FileUtils.RECURSIVE | FileUtils.RETRY);
-		return result;
-	}
-
-	/**
-	 * Cleanup: delete the "temporary" folder and all children
-	 *
-	 * @throws IOException
-	 */
-	public void deleteTempDirs() throws IOException {
-		File rootDir = getBaseTempDir();
-		if (rootDir.exists())
-			FileUtils.delete(rootDir, FileUtils.RECURSIVE | FileUtils.RETRY);
-	}
-
-	/**
-	 * Read the stream into a String
-	 *
-	 * @param inputStream
-	 * @return the contents of the stream
-	 * @throws IOException
-	 */
-	public String slurpAndClose(InputStream inputStream) throws IOException {
-		StringBuilder stringBuilder = new StringBuilder();
-		try {
-			int ch;
-			while ((ch = inputStream.read()) != -1) {
-				stringBuilder.append((char) ch);
-			}
-		} finally {
-			inputStream.close();
-		}
-		return stringBuilder.toString();
-	}
-
-	/**
-	 * Add a file to an existing project
-	 *
-	 * @param project
-	 *            the project
-	 * @param path
-	 *            e.g. "folder1/folder2/test.txt"
-	 * @param content
-	 *            the contents
-	 * @return the file
-	 * @throws CoreException
-	 *             if the file can not be created
-	 * @throws UnsupportedEncodingException
-	 */
-	public IFile addFileToProject(IProject project, String path, String content) throws CoreException, UnsupportedEncodingException {
-		IPath filePath = new Path(path);
-		IFolder folder = null;
-		for (int i = 0; i < filePath.segmentCount() - 1; i++) {
-			if (folder == null) {
-				folder = project.getFolder(filePath.segment(i));
-			} else {
-				folder = folder.getFolder(filePath.segment(i));
-			}
-			if (!folder.exists())
-				folder.create(false, true, null);
-		}
-		IFile file = project.getFile(filePath);
-		file.create(new ByteArrayInputStream(content.getBytes(project
-				.getDefaultCharset())), true, null);
-		return file;
-	}
-
-	/**
-	 * Change the content of a file
-	 *
-	 * @param project
-	 * @param file
-	 * @param newContent
-	 * @return the file
-	 * @throws CoreException
-	 * @throws UnsupportedEncodingException
-	 */
-	public IFile changeContentOfFile(IProject project, IFile file, String newContent) throws UnsupportedEncodingException, CoreException {
-		file.setContents(new ByteArrayInputStream(newContent.getBytes(project
-				.getDefaultCharset())), 0, null);
-		return file;
-	}
-
-	/**
-	 * Create a project in the base directory of temp dirs
-	 *
-	 * @param projectName
-	 *            project name
-	 * @return the project with a location pointing to the local file system
-	 * @throws Exception
-	 */
-	public IProject createProjectInLocalFileSystem(
-			String projectName) throws Exception {
-		return createProjectInLocalFileSystem(getBaseTempDir(), projectName);
-	}
-
-	/**
-	 * Create a project in the local file system
-	 *
-	 * @param parentFile
-	 *            the parent directory
-	 * @param projectName
-	 *            project name
-	 * @return the project with a location pointing to the local file system
-	 * @throws Exception
-	 */
-	public IProject createProjectInLocalFileSystem(File parentFile,
-			String projectName) throws Exception {
-		IProject project = ResourcesPlugin.getWorkspace().getRoot()
-				.getProject(projectName);
-		if (project.exists()) {
-			project.delete(true, null);
-		}
-		File testFile = new File(parentFile, projectName);
-		if (testFile.exists())
-			FileUtils.delete(testFile, FileUtils.RECURSIVE | FileUtils.RETRY);
-
-		IProjectDescription desc = ResourcesPlugin.getWorkspace()
-				.newProjectDescription(projectName);
-		desc.setLocation(new Path(new File(parentFile, projectName).getPath()));
-		project.create(desc, null);
-		project.open(null);
-		return project;
-	}
-
-	/**
-	 * verifies that repository contains exactly the given files.
-	 * @param repository
-	 * @param paths
-	 * @throws Exception
-	 */
-	public void assertRepositoryContainsFiles(Repository repository,
-			String[] paths) throws Exception {
-		Set<String> expectedfiles = new HashSet<String>();
-		for (String path : paths)
-			expectedfiles.add(path);
-		TreeWalk treeWalk = new TreeWalk(repository);
-		treeWalk.addTree(repository.resolve("HEAD^{tree}"));
-		treeWalk.setRecursive(true);
-		while (treeWalk.next()) {
-			String path = treeWalk.getPathString();
-			if (!expectedfiles.contains(path))
-				fail("Repository contains unexpected expected file " + path);
-			expectedfiles.remove(path);
-		}
-		if (expectedfiles.size() > 0) {
-			StringBuilder message = new StringBuilder(
-					"Repository does not contain expected files: ");
-			for (String path : expectedfiles) {
-				message.append(path);
-				message.append(" ");
-			}
-			fail(message.toString());
-		}
-	}
-
-	/**
-	 * verifies that repository contains exactly the given files with the given
-	 * content. Usage example:<br>
-	 *
-	 * <code>
-	 * assertRepositoryContainsFiles(repository, "foo/a.txt", "content of A",
-	 *                                           "foo/b.txt", "content of B")
-	 * </code>
-	 * @param repository
-	 * @param args
-	 * @throws Exception
-	 */
-	public void assertRepositoryContainsFilesWithContent(Repository repository,
-			String... args) throws Exception {
-		HashMap<String, String> expectedfiles = mkmap(args);
-		TreeWalk treeWalk = new TreeWalk(repository);
-		treeWalk.addTree(repository.resolve("HEAD^{tree}"));
-		treeWalk.setRecursive(true);
-		while (treeWalk.next()) {
-			String path = treeWalk.getPathString();
-			assertTrue(expectedfiles.containsKey(path));
-			ObjectId objectId = treeWalk.getObjectId(0);
-			byte[] expectedContent = expectedfiles.get(path).getBytes();
-			byte[] repoContent = treeWalk.getObjectReader().open(objectId)
-					.getBytes();
-			if (!Arrays.equals(repoContent, expectedContent)) {
-				fail("File " + path + " has repository content "
-						+ new String(repoContent)
-						+ " instead of expected content "
-						+ new String(expectedContent));
-			}
-			expectedfiles.remove(path);
-		}
-		if (expectedfiles.size() > 0) {
-			StringBuilder message = new StringBuilder(
-					"Repository does not contain expected files: ");
-			for (String path : expectedfiles.keySet()) {
-				message.append(path);
-				message.append(" ");
-			}
-			fail(message.toString());
-		}
-	}
-
-	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<String, String>();
-		for (int i = 0; i < args.length; i += 2) {
-			map.put(args[i], args[i+1]);
-		}
-		return map;
-	}
-
-	File getWorkspaceSupplement() throws IOException {
-		return createTempDir("wssupplement");
-	}
-
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/UtilsTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/UtilsTest.java
deleted file mode 100644
index 4269fe2..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/UtilsTest.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2011, Jens Baumgart <jens.baumgart@sap.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.test;
-
-import static org.junit.Assert.assertEquals;
-
-import org.eclipse.egit.core.internal.Utils;
-import org.junit.Test;
-
-public class UtilsTest {
-
-	@Test
-	public void testLineEndingNormalization() {
-		String str = "";
-		String result = Utils.normalizeLineEndings(str);
-		assertEquals(result, "");
-
-		str = "Line 1";
-		result = Utils.normalizeLineEndings(str);
-		assertEquals("Line 1", result);
-
-		str = "Line 1\r\nLine 2";
-		result = Utils.normalizeLineEndings(str);
-		assertEquals("Line 1\nLine 2", result);
-
-		str = "Line 1\r\nLine 2\r";
-		result = Utils.normalizeLineEndings(str);
-		assertEquals("Line 1\nLine 2\n", result);
-
-		str = "Line 1\r\nLine 2\nLine 3\rLine 4\r\nLine 5\rLine 6\r\n Line 7\r";
-		result = Utils.normalizeLineEndings(str);
-		assertEquals(
-				"Line 1\nLine 2\nLine 3\nLine 4\nLine 5\nLine 6\n Line 7\n",
-				result);
-	}
-
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/indexDiff/IndexDiffCacheTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/indexDiff/IndexDiffCacheTest.java
deleted file mode 100644
index 7eb1b0b..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/indexDiff/IndexDiffCacheTest.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2011, 2012 Jens Baumgart <jens.baumgart@sap.com> and others.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.test.indexDiff;
-
-import static org.hamcrest.CoreMatchers.not;
-import static org.hamcrest.Matchers.hasItem;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.internal.indexdiff.IndexDiffCache;
-import org.eclipse.egit.core.internal.indexdiff.IndexDiffCacheEntry;
-import org.eclipse.egit.core.internal.indexdiff.IndexDiffChangedListener;
-import org.eclipse.egit.core.internal.indexdiff.IndexDiffData;
-import org.eclipse.egit.core.op.ConnectProviderOperation;
-import org.eclipse.egit.core.test.GitTestCase;
-import org.eclipse.egit.core.test.TestRepository;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.lib.Repository;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class IndexDiffCacheTest extends GitTestCase {
-
-	TestRepository testRepository;
-
-	Repository repository;
-
-	private AtomicBoolean listenerCalled;
-
-	private AtomicReference<IndexDiffData> indexDiffDataResult;
-
-	@Before
-	public void setUp() throws Exception {
-		super.setUp();
-		testRepository = new TestRepository(gitDir);
-		repository = testRepository.getRepository();
-	}
-
-	@After
-	public void tearDown() throws Exception {
-		testRepository.dispose();
-		repository = null;
-		super.tearDown();
-	}
-
-	@Test
-	public void testAddingAFile() throws Exception {
-		new ConnectProviderOperation(project.project, repository.getDirectory())
-				.execute(null);
-		// create first commit containing a dummy file
-		testRepository
-				.createInitialCommit("testBranchOperation\n\nfirst commit\n");
-		prepareCacheEntry();
-		waitForListenerCalled();
-		final String fileName = "aFile";
-		// This call should trigger an indexDiffChanged event (triggered via
-		// resource changed event)
-		project.createFile(fileName, "content".getBytes("UTF-8"));
-		IndexDiffData indexDiffData = waitForListenerCalled();
-		String path = project.project.getFile(fileName).getFullPath()
-				.toString().substring(1);
-		if (!indexDiffData.getUntracked().contains(path))
-			fail("IndexDiffData did not contain aFile as untracked");
-		// This call should trigger an indexDiffChanged event
-		new Git(repository).add().addFilepattern(path).call();
-		IndexDiffData indexDiffData2 = waitForListenerCalled();
-		if (indexDiffData2.getUntracked().contains(path))
-			fail("IndexDiffData contains aFile as untracked");
-		if (!indexDiffData2.getAdded().contains(path))
-			fail("IndexDiffData does not contain aFile as added");
-	}
-
-	@Test
-	public void testAddFileFromUntrackedFolder() throws Exception {
-		testRepository.connect(project.project);
-		testRepository.addToIndex(project.project);
-		testRepository.createInitialCommit("testAddFileFromUntrackedFolder\n\nfirst commit\n");
-		prepareCacheEntry();
-
-		project.createFolder("folder");
-		project.createFolder("folder/a");
-		project.createFolder("folder/b");
-		IFile fileA = project.createFile("folder/a/file", new byte[] {});
-		project.createFile("folder/b/file", new byte[] {});
-
-		IndexDiffData data1 = waitForListenerCalled();
-		assertThat(data1.getUntrackedFolders(), hasItem("Project-1/folder/"));
-
-		testRepository.track(fileA.getLocation().toFile());
-
-		IndexDiffData data2 = waitForListenerCalled();
-		assertThat(data2.getAdded(), hasItem("Project-1/folder/a/file"));
-		assertThat(data2.getUntrackedFolders(), not(hasItem("Project-1/folder/")));
-		assertThat(data2.getUntrackedFolders(), not(hasItem("Project-1/folder/a")));
-		assertThat(data2.getUntrackedFolders(), hasItem("Project-1/folder/b/"));
-	}
-
-	@Test
-	public void testAddIgnoredFolder() throws Exception {
-		testRepository.connect(project.project);
-		project.createFile(".gitignore", "ignore\n".getBytes("UTF-8"));
-		project.createFolder("ignore");
-		project.createFile("ignore/file.txt", new byte[] {});
-		project.createFolder("sub");
-		testRepository.addToIndex(project.project);
-		testRepository.createInitialCommit("testAddFileInIgnoredFolder\n\nfirst commit\n");
-		prepareCacheEntry();
-
-		IndexDiffData data1 = waitForListenerCalled();
-		assertThat(data1.getIgnoredNotInIndex(), hasItem("Project-1/ignore"));
-
-		project.createFolder("sub/ignore");
-
-		IndexDiffData data2 = waitForListenerCalled();
-		assertThat(data2.getIgnoredNotInIndex(), hasItem("Project-1/ignore"));
-		assertThat(data2.getIgnoredNotInIndex(), hasItem("Project-1/sub/ignore"));
-
-		// Must not change anything (ignored path starts with this string, but
-		// it's not a prefix path of it)
-		project.createFile("sub/ignorenot", new byte[] {});
-
-		IndexDiffData data3 = waitForListenerCalled();
-		assertThat(data3.getUntracked(), hasItem("Project-1/sub/ignorenot"));
-		assertThat(data3.getIgnoredNotInIndex(), hasItem("Project-1/ignore"));
-		assertThat(data3.getIgnoredNotInIndex(), hasItem("Project-1/sub/ignore"));
-	}
-
-	@Test
-	public void testRemoveIgnoredFile() throws Exception {
-		testRepository.connect(project.project);
-		project.createFile(".gitignore", "ignore\n".getBytes("UTF-8"));
-		project.createFolder("sub");
-		IFile file = project.createFile("sub/ignore", new byte[] {});
-		testRepository.addToIndex(project.project);
-		testRepository.createInitialCommit("testRemoveIgnoredFile\n\nfirst commit\n");
-		prepareCacheEntry();
-
-		IndexDiffData data1 = waitForListenerCalled();
-		assertThat(data1.getIgnoredNotInIndex(), hasItem("Project-1/sub/ignore"));
-
-		// Must not change anything (ignored path starts with this string, but
-		// it's not a prefix path of it)
-		project.createFile("sub/ignorenot", new byte[] {});
-
-		IndexDiffData data2 = waitForListenerCalled();
-		assertThat(data2.getIgnoredNotInIndex(), hasItem("Project-1/sub/ignore"));
-
-		file.delete(false, null);
-
-		IndexDiffData data3 = waitForListenerCalled();
-		assertThat(data3.getIgnoredNotInIndex(), not(hasItem("Project-1/sub/ignore")));
-	}
-
-	private void prepareCacheEntry() {
-		IndexDiffCache indexDiffCache = Activator.getDefault()
-				.getIndexDiffCache();
-		// This call should trigger an indexDiffChanged event
-		IndexDiffCacheEntry cacheEntry = indexDiffCache
-				.getIndexDiffCacheEntry(repository);
-		listenerCalled = new AtomicBoolean(false);
-		indexDiffDataResult = new AtomicReference<IndexDiffData>(
-				null);
-		cacheEntry.addIndexDiffChangedListener(new IndexDiffChangedListener() {
-			public void indexDiffChanged(Repository repo,
-					IndexDiffData indexDiffData) {
-				listenerCalled.set(true);
-				indexDiffDataResult.set(indexDiffData);
-			}
-		});
-	}
-
-	private IndexDiffData waitForListenerCalled() throws InterruptedException {
-		long time = 0;
-		while (!listenerCalled.get() && time < 60000) {
-			Thread.sleep(100);
-			time += 100;
-		}
-		assertTrue("indexDiffChanged was not called after " + time + " ms", listenerCalled.get());
-		listenerCalled.set(false);
-		return indexDiffDataResult.get();
-	}
-
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/internal/mapping/HistoryTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/internal/mapping/HistoryTest.java
index 1f6d67a..4a0dbbd 100644
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/internal/mapping/HistoryTest.java
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/internal/mapping/HistoryTest.java
@@ -21,10 +21,10 @@
 
 import org.eclipse.core.resources.IStorage;
 import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.egit.core.GitProvider;
+import org.eclipse.egit.core.internal.GitProvider;
+import org.eclipse.egit.core.internal.op.ConnectProviderOperation;
 import org.eclipse.egit.core.internal.storage.GitFileRevision;
-import org.eclipse.egit.core.op.ConnectProviderOperation;
-import org.eclipse.egit.core.test.GitTestCase;
+import org.eclipse.egit.core.internal.test.GitTestCase;
 import org.eclipse.jgit.api.Git;
 import org.eclipse.jgit.lib.PersonIdent;
 import org.eclipse.jgit.lib.Repository;
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/AddOperationTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/AddOperationTest.java
deleted file mode 100644
index 0f662e8..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/AddOperationTest.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2010, Stefan Lay <stefan.lay@sap.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.test.op;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.egit.core.op.AddToIndexOperation;
-import org.eclipse.egit.core.test.GitTestCase;
-import org.eclipse.egit.core.test.TestRepository;
-import org.eclipse.jgit.lib.Constants;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class AddOperationTest extends GitTestCase {
-
-	private List<IResource> resources = new ArrayList<IResource>();
-
-	TestRepository testRepository;
-
-	@Before
-	public void setUp() throws Exception {
-		super.setUp();
-		gitDir = new File(project.getProject()
-				.getLocationURI().getPath(), Constants.DOT_GIT);
-		testRepository = new TestRepository(gitDir);
-		testRepository.connect(project.getProject());
-	}
-
-	@After
-	public void tearDown() throws Exception {
-		testRepository.dispose();
-		super.tearDown();
-	}
-
-	@Test
-	public void testTrackFile() throws Exception {
-		IFile file1 = testUtils.addFileToProject(project.getProject(), "a.txt",
-				"some text");
-
-		assertFalse(testRepository.inIndex(file1.getLocation()
-				.toPortableString()));
-
-		resources.add(file1);
-		new AddToIndexOperation(resources).execute(null);
-
-		assertTrue(testRepository.inIndex(file1.getLocation()
-				.toPortableString()));
-	}
-
-	@Test
-	public void testTrackFilesInFolder() throws Exception {
-		IFile file1 = testUtils.addFileToProject(project.getProject(),
-				"sub/a.txt", "some text");
-		IFile file2 = testUtils.addFileToProject(project.getProject(),
-				"sub/b.txt", "some text");
-
-		assertFalse(testRepository.inIndex(file1.getLocation()
-				.toPortableString()));
-		assertFalse(testRepository.inIndex(file2.getLocation()
-				.toPortableString()));
-
-		resources.add(project.getProject().getFolder("sub"));
-		new AddToIndexOperation(resources).execute(null);
-
-		assertTrue(testRepository.inIndex(file1.getLocation()
-				.toPortableString()));
-		assertTrue(testRepository.inIndex(file2.getLocation()
-				.toPortableString()));
-	}
-
-	@Test
-	public void testAddFile() throws Exception {
-		IFile file1 = testUtils.addFileToProject(project.getProject(), "a.txt",
-				"some text");
-
-		resources.add(file1);
-		new AddToIndexOperation(resources).execute(null);
-
-		testRepository.commit("first commit");
-
-		assertEquals(file1.getLocalTimeStamp(),
-				testRepository.lastModifiedInIndex(file1.getLocation()
-						.toPortableString()));
-
-		Thread.sleep(1000);
-		file1.setContents(
-				new ByteArrayInputStream("other text".getBytes(project.project
-						.getDefaultCharset())), 0, null);
-
-		assertFalse(file1.getLocalTimeStamp() == testRepository
-				.lastModifiedInIndex(file1.getLocation().toPortableString()));
-
-		new AddToIndexOperation(resources).execute(null);
-
-		assertTrue(testRepository.inIndex(file1.getLocation()
-				.toPortableString()));
-		// does not work yet due to the racy git problem: DirCache.writeTo
-		// smudges the
-		// timestamp of an added file
-		 assertEquals(file1.getLocalTimeStamp() / 10,
-				 testRepository.lastModifiedInIndex(file1.getLocation().toPortableString()) / 10);
-	}
-
-	@Test
-	public void testAddFilesInFolder() throws Exception {
-		IFile file1 = testUtils.addFileToProject(project.getProject(),
-				"sub/a.txt", "some text");
-		IFile file2 = testUtils.addFileToProject(project.getProject(),
-				"sub/b.txt", "some text");
-
-		resources.add(project.getProject().getFolder("sub"));
-		new AddToIndexOperation(resources).execute(null);
-
-		testRepository.commit("first commit");
-
-		assertEquals(file1.getLocalTimeStamp(),
-				testRepository.lastModifiedInIndex(file1.getLocation()
-						.toPortableString()));
-
-		Thread.sleep(1000);
-
-		file1.setContents(
-				new ByteArrayInputStream("other text".getBytes(project.project
-						.getDefaultCharset())), 0, null);
-		file2.setContents(
-				new ByteArrayInputStream("other text".getBytes(project.project
-						.getDefaultCharset())), 0, null);
-
-		assertFalse(file1.getLocalTimeStamp() == testRepository
-				.lastModifiedInIndex(file1.getLocation().toPortableString()));
-		assertFalse(file2.getLocalTimeStamp() == testRepository
-				.lastModifiedInIndex(file1.getLocation().toPortableString()));
-
-		new AddToIndexOperation(resources).execute(null);
-
-		assertTrue(testRepository.inIndex(file1.getLocation()
-				.toPortableString()));
-		assertTrue(testRepository.inIndex(file2.getLocation()
-				.toPortableString()));
-
-		 assertEquals(file1.getLocalTimeStamp() / 10,
-				 testRepository.lastModifiedInIndex(file1.getLocation().toPortableString()) / 10);
-		 assertEquals(file2.getLocalTimeStamp() / 10,
-				 testRepository.lastModifiedInIndex(file2.getLocation().toPortableString()) / 10);
-	}
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/BranchOperationTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/BranchOperationTest.java
deleted file mode 100644
index 2f6b0de..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/BranchOperationTest.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2010, Jens Baumgart <jens.baumgart@sap.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.test.op;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import java.io.File;
-
-import org.eclipse.egit.core.op.BranchOperation;
-import org.eclipse.egit.core.test.GitTestCase;
-import org.eclipse.egit.core.test.TestRepository;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.lib.Repository;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class BranchOperationTest extends GitTestCase{
-
-	private static final String TEST = Constants.R_HEADS + "test";
-	private static final String MASTER = Constants.R_HEADS + "master";
-	TestRepository testRepository;
-	Repository repository;
-
-	@Before
-	public void setUp() throws Exception {
-		super.setUp();
-		testRepository = new TestRepository(gitDir);
-		repository = testRepository.getRepository();
-	}
-
-	@After
-	public void tearDown() throws Exception {
-		testRepository.dispose();
-		repository = null;
-		super.tearDown();
-	}
-
-	@Test
-	public void testBranchOperation() throws Exception {
-		// create first commit containing a dummy file
-		testRepository.createInitialCommit("testBranchOperation\n\nfirst commit\n");
-		// create branch test and switch to branch test
-		testRepository.createBranch(MASTER, TEST);
-		new BranchOperation(repository, TEST).execute(null);
-		assertTrue(repository.getFullBranch().equals(TEST));
-		// add .project to version control and commit
-		String path = project.getProject().getLocation().append(".project").toOSString();
-		File file = new File(path);
-		testRepository.track(file);
-		testRepository.commit("Add .project file");
-		// switch back to master branch
-		// .project must disappear, related Eclipse project must be deleted
-		new BranchOperation(repository, MASTER).execute(null);
-		assertFalse(file.exists());
-		assertFalse(project.getProject().exists());
-		// switch back to master test
-		// .project must reappear
-		new BranchOperation(repository, TEST).execute(null);
-		assertTrue(file.exists());
-	}
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/CloneOperationTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/CloneOperationTest.java
deleted file mode 100644
index e46c41f..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/CloneOperationTest.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2011, Stefan Lay <stefan.lay@sap.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-
-package org.eclipse.egit.core.test.op;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.io.File;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.egit.core.op.CloneOperation;
-import org.eclipse.egit.core.op.CloneOperation.PostCloneTask;
-import org.eclipse.egit.core.op.ConfigureFetchAfterCloneTask;
-import org.eclipse.egit.core.op.ConfigurePushAfterCloneTask;
-import org.eclipse.egit.core.test.DualRepositoryTestCase;
-import org.eclipse.egit.core.test.TestRepository;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.api.errors.GitAPIException;
-import org.eclipse.jgit.lib.ConfigConstants;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.jgit.internal.storage.file.FileRepository;
-import org.eclipse.jgit.transport.URIish;
-import org.eclipse.jgit.util.FileUtils;
-import org.junit.Before;
-import org.junit.Test;
-
-public class CloneOperationTest extends DualRepositoryTestCase {
-
-	File workdir;
-
-	File workdir2;
-
-	@Before
-	public void setUp() throws Exception {
-		workdir = testUtils.createTempDir("Repository1");
-		workdir2 = testUtils.createTempDir("Repository2");
-
-		repository1 = new TestRepository(new File(workdir, Constants.DOT_GIT));
-
-		File file = new File(workdir, "file1.txt");
-		FileUtils.createNewFile(file);
-		Git git = new Git(repository1.getRepository());
-		git.add().addFilepattern("file1.txt").call();
-
-		git.commit().setMessage("first commit").call();
-	}
-
-	@Test
-	public void testClone() throws Exception {
-		URIish uri = new URIish("file:///"
-				+ repository1.getRepository().getDirectory().toString());
-		CloneOperation clop = new CloneOperation(uri, true, null, workdir2,
-				"refs/heads/master", "origin", 0);
-		clop.run(null);
-
-		Repository clonedRepo = new FileRepository(new File(workdir2,
-				Constants.DOT_GIT));
-		assertEquals(
-				"",
-				uri.toString(),
-				clonedRepo.getConfig().getString(
-						ConfigConstants.CONFIG_REMOTE_SECTION, "origin", "url"));
-		assertEquals(
-				"",
-				"+refs/heads/*:refs/remotes/origin/*",
-				clonedRepo.getConfig().getString(
-						ConfigConstants.CONFIG_REMOTE_SECTION, "origin",
-						"fetch"));
-
-		File file = new File(workdir2, "file1.txt");
-		assertTrue(file.exists());
-	}
-
-	@Test
-	public void testSimplePostCloneTask() throws Exception {
-		URIish uri = new URIish("file:///"
-				+ repository1.getRepository().getDirectory().toString());
-		CloneOperation clop = new CloneOperation(uri, true, null, workdir2,
-				"refs/heads/master", "origin", 0);
-
-		final File[] repoDir = new File[1];
-		clop.addPostCloneTask(new PostCloneTask() {
-
-			public void execute(Repository repository, IProgressMonitor monitor)
-					throws CoreException {
-				repoDir[0] = repository.getDirectory();
-
-			}
-		});
-		clop.run(null);
-		File newRepoDir = new File(workdir2, Constants.DOT_GIT);
-		assertEquals(newRepoDir, repoDir[0]);
-	}
-
-	@Test
-	public void testConfigurePushAfterCloneTask() throws Exception {
-		URIish uri = new URIish("file:///"
-				+ repository1.getRepository().getDirectory().toString());
-		CloneOperation clop = new CloneOperation(uri, true, null, workdir2,
-				"refs/heads/master", "origin", 0);
-
-		clop.addPostCloneTask(new ConfigurePushAfterCloneTask("origin",
-				"HEAD:refs/for/master", new URIish("file:///pushtarget")));
-		clop.run(null);
-		Repository clonedRepo = new FileRepository(new File(workdir2,
-				Constants.DOT_GIT));
-		assertEquals(
-				"",
-				"HEAD:refs/for/master",
-				clonedRepo.getConfig()
-				.getString(ConfigConstants.CONFIG_REMOTE_SECTION,
-						"origin", "push"));
-		assertEquals(
-				"",
-				"file:///pushtarget",
-				clonedRepo.getConfig().getString(
-						ConfigConstants.CONFIG_REMOTE_SECTION, "origin",
-						"pushurl"));
-	}
-
-	@Test
-	public void testConfigureFetchAfterCloneTask() throws Exception {
-		createNoteInOrigin();
-
-		URIish uri = new URIish("file:///"
-				+ repository1.getRepository().getDirectory().toString());
-		CloneOperation clop = new CloneOperation(uri, true, null, workdir2,
-				"refs/heads/master", "origin", 0);
-
-		clop.addPostCloneTask(new ConfigureFetchAfterCloneTask("origin",
-				"refs/notes/review:refs/notes/review"));
-		clop.run(null);
-		Repository clonedRepo = new FileRepository(new File(workdir2,
-				Constants.DOT_GIT));
-		assertTrue(
-				clonedRepo.getConfig()
-				.getStringList(ConfigConstants.CONFIG_REMOTE_SECTION,
-						"origin", "fetch")[1].equals("refs/notes/review:refs/notes/review"));
-		Git clonedGit = new Git(clonedRepo);
-		assertEquals(1, clonedGit.notesList().setNotesRef("refs/notes/review").call().size());
-	}
-
-	protected void createNoteInOrigin() throws GitAPIException {
-		Git git = new Git(repository1.getRepository());
-		git.add().addFilepattern("file.txt").call();
-		RevCommit commit = git.commit().setMessage("Initial commit").call();
-		git.notesAdd().setNotesRef("refs/notes/review").setObjectId(commit).setMessage("text").call();
-	}
-
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/CommitOperationTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/CommitOperationTest.java
deleted file mode 100644
index fae6e58..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/CommitOperationTest.java
+++ /dev/null
@@ -1,318 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2010, Stefan Lay <stefan.lay@sap.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-
-package org.eclipse.egit.core.test.op;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.egit.core.op.AddToIndexOperation;
-import org.eclipse.egit.core.op.CommitOperation;
-import org.eclipse.egit.core.test.GitTestCase;
-import org.eclipse.egit.core.test.TestRepository;
-import org.eclipse.egit.core.test.TestUtils;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.jgit.treewalk.TreeWalk;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class CommitOperationTest extends GitTestCase {
-
-	private static List<IFile> EMPTY_FILE_LIST = new ArrayList<IFile>();
-
-	private List<IResource> resources = new ArrayList<IResource>();
-
-	TestRepository testRepository;
-
-	Repository repository;
-
-	@Before
-	public void setUp() throws Exception {
-		super.setUp();
-		gitDir = new File(project.getProject()
-				.getLocationURI().getPath(), Constants.DOT_GIT);
-		testRepository = new TestRepository(gitDir);
-		repository = testRepository.getRepository();
-		testRepository.connect(project.getProject());
-	}
-
-	@After
-	public void tearDown() throws Exception {
-		testRepository.dispose();
-		repository = null;
-		super.tearDown();
-	}
-
-	@Test
-	public void testCommitAddedToIndexDeletedInWorkspace() throws Exception {
-		testUtils.addFileToProject(project.getProject(), "foo/a.txt", "some text");
-		resources.add(project.getProject().getFolder("foo"));
-		new AddToIndexOperation(resources).execute(null);
-		CommitOperation commitOperation = new CommitOperation(null, null, TestUtils.AUTHOR, TestUtils.COMMITTER, "first commit");
-		commitOperation.setCommitAll(true);
-		commitOperation.setRepository(repository);
-		commitOperation.execute(null);
-
-		testUtils.addFileToProject(project.getProject(), "zar/b.txt", "some text");
-		resources.add(project.getProject().getFolder("zar"));
-		new AddToIndexOperation(resources).execute(null);
-		IFile zarFile = project.getProject().getFile("zar/b.txt");
-		IPath zarFilePath = zarFile.getLocation();
-		// delete file and refresh. Deleting using the resource would trigger
-		// GitMoveDeleteHook which removes the file from the index
-		assertTrue("could not delete file " + zarFilePath.toOSString(),
-				zarFilePath.toFile().delete());
-		zarFile.refreshLocal(0, null);
-
-		assertFalse(project.getProject().getFile("zar/b.txt").exists());
-
-		IFile[] filesToCommit = new IFile[] { project.getProject().getFile("zar/b.txt") };
-		commitOperation = new CommitOperation(filesToCommit, null, TestUtils.AUTHOR, TestUtils.COMMITTER, "first commit");
-		commitOperation.setRepository(repository);
-		try {
-			commitOperation.execute(null);
-			// TODO this is very ugly. CommitCommand should be extended
-			// not to throw an JGitInternalException in case of an empty
-			// commit
-			fail("expected CoreException");
-		} catch (CoreException e) {
-			assertEquals("No changes", e.getCause().getMessage());
-		}
-
-		TreeWalk treeWalk = new TreeWalk(repository);
-		treeWalk.addTree(repository.resolve("HEAD^{tree}"));
-		assertTrue(treeWalk.next());
-		assertEquals("foo", treeWalk.getPathString());
-		treeWalk.enterSubtree();
-		assertTrue(treeWalk.next());
-		assertEquals("foo/a.txt", treeWalk.getPathString());
-		assertFalse(treeWalk.next());
-	}
-
-	@Test
-	public void testCommitAll() throws Exception {
-		IFile file1 = testUtils.addFileToProject(project.getProject(),
-				"sub/a.txt", "some text");
-		testUtils.addFileToProject(project.getProject(),
-				"sub/b.txt", "some text");
-
-		resources.add(project.getProject().getFolder("sub"));
-		new AddToIndexOperation(resources).execute(null);
-		CommitOperation commitOperation = new CommitOperation(null, null, TestUtils.AUTHOR,
-				TestUtils.COMMITTER, "first commit");
-		commitOperation.setCommitAll(true);
-		commitOperation.setRepository(repository);
-		commitOperation.execute(null);
-
-		Git git = new Git(repository);
-		Iterator<RevCommit> commits = git.log().call().iterator();
-		RevCommit firstCommit = commits.next();
-		assertTrue(firstCommit.getCommitTime() > 0);
-
-		assertEquals("first commit", firstCommit.getFullMessage());
-
-		testUtils.changeContentOfFile(project.getProject(), file1, "changed text");
-
-		commitOperation = new CommitOperation(null, null, TestUtils.AUTHOR,
-				TestUtils.COMMITTER, "second commit");
-		commitOperation.setCommitAll(true);
-		commitOperation.setRepository(repository);
-		commitOperation.execute(null);
-
-		git = new Git(repository);
-		commits = git.log().call().iterator();
-		RevCommit secondCommit = commits.next();
-		assertTrue(secondCommit.getCommitTime() > 0);
-
-		assertEquals("second commit", secondCommit.getFullMessage());
-		secondCommit.getParent(0).equals(firstCommit);
-		assertEquals("The Author", secondCommit.getAuthorIdent().getName());
-		assertEquals("The.author@some.com", secondCommit.getAuthorIdent().getEmailAddress());
-		assertEquals("The Commiter", secondCommit.getCommitterIdent().getName());
-		assertEquals("The.committer@some.com", secondCommit.getCommitterIdent().getEmailAddress());
-	}
-
-	@Test
-	public void testCommitEmptiedTree() throws Exception {
-		// Set up a directory structure
-		testUtils.addFileToProject(project.getProject(),
-				"sub1/a.txt", "some text");
-		testUtils.addFileToProject(project.getProject(),
-				"sub2/b.txt", "some text");
-		resources.add(project.getProject().getFolder("sub1"));
-		resources.add(project.getProject().getFolder("sub2"));
-		new AddToIndexOperation(resources).execute(null);
-		CommitOperation commitOperation = new CommitOperation(null, null, TestUtils.AUTHOR,
-				TestUtils.COMMITTER, "first commit");
-		commitOperation.setCommitAll(true);
-		commitOperation.setRepository(repository);
-		commitOperation.execute(null);
-
-		Git git = new Git(repository);
-		Iterator<RevCommit> commits = git.log().call().iterator();
-		RevCommit secondCommit = commits.next();
-		TreeWalk treeWalk = new TreeWalk(repository);
-		treeWalk.addTree(secondCommit.getTree().getId());
-		treeWalk.setRecursive(true);
-		treeWalk.setPostOrderTraversal(true);
-		assertTrue(treeWalk.next());
-		assertEquals("sub1/a.txt", treeWalk.getPathString());
-		assertTrue(treeWalk.next());
-		assertEquals("sub1", treeWalk.getPathString());
-		assertTrue(treeWalk.next());
-		assertEquals("sub2/b.txt", treeWalk.getPathString());
-		assertTrue(treeWalk.next());
-		assertEquals("sub2", treeWalk.getPathString());
-		assertFalse(treeWalk.next());
-
-		project.getProject().getFolder("sub2").delete(IResource.FORCE, null);
-		IFile[] filesToCommit = { project.getProject().getFile("sub2/b.txt") };
-		ArrayList<IFile> notIndexed = new ArrayList<IFile>();
-		notIndexed.add(filesToCommit[0]);
-		ArrayList<IFile> notTracked = new ArrayList<IFile>();
-		commitOperation = new CommitOperation(filesToCommit, notTracked, TestUtils.AUTHOR, TestUtils.COMMITTER, "second commit");
-		commitOperation.setCommitAll(false);
-		commitOperation.execute(null);
-
-		git = new Git(repository);
-		commits = git.log().call().iterator();
-		secondCommit = commits.next();
-		treeWalk = new TreeWalk(repository);
-		treeWalk.addTree(secondCommit.getTree().getId());
-		treeWalk.setRecursive(true);
-		treeWalk.setPostOrderTraversal(true);
-		assertTrue(treeWalk.next());
-		assertEquals("sub1/a.txt", treeWalk.getPathString());
-		assertTrue(treeWalk.next());
-		assertEquals("sub1", treeWalk.getPathString());
-		assertFalse(treeWalk.next());
-	}
-
-	@Test
-	public void testCommitUntracked() throws Exception {
-		IFile fileA = testUtils.addFileToProject(project.getProject(),
-				"foo/a.txt", "some text");
-		IFile fileB = testUtils.addFileToProject(project.getProject(),
-				"foo/b.txt", "some text");
-		testUtils.addFileToProject(project.getProject(), "foo/c.txt",
-				"some text");
-		IFile[] filesToCommit = { fileA, fileB };
-		CommitOperation commitOperation = new CommitOperation(filesToCommit,
-				Arrays.asList(filesToCommit), TestUtils.AUTHOR,
-				TestUtils.COMMITTER, "first commit");
-		commitOperation.execute(null);
-		testUtils.assertRepositoryContainsFiles(repository, getRepoRelativePaths(filesToCommit));
-	}
-
-	private String[] getRepoRelativePaths(IFile[] files) {
-		ArrayList<String> result = new ArrayList<String>();
-		for (IFile file:files)
-			result.add(file.getProjectRelativePath().toString());
-		return result.toArray(new String[result.size()]);
-	}
-
-	@Test
-	public void testCommitStaged() throws Exception {
-		IFile fileA = testUtils.addFileToProject(project.getProject(),
-				"foo/a.txt", "some text");
-		IFile fileB = testUtils.addFileToProject(project.getProject(),
-				"foo/b.txt", "some text");
-		IFile[] filesToCommit = { fileA, fileB };
-		CommitOperation commitOperation = new CommitOperation(filesToCommit,
-				Arrays.asList(filesToCommit), TestUtils.AUTHOR,
-				TestUtils.COMMITTER, "first commit");
-		commitOperation.execute(null);
-		testUtils.changeContentOfFile(project.getProject(), fileA,
-				"new content of A");
-		testUtils.changeContentOfFile(project.getProject(), fileB,
-				"new content of B");
-		resources.add(fileA);
-		resources.add(fileB);
-		new AddToIndexOperation(resources).execute(null);
-		commitOperation = new CommitOperation(filesToCommit, EMPTY_FILE_LIST,
-				TestUtils.AUTHOR, TestUtils.COMMITTER, "second commit");
-		commitOperation.execute(null);
-
-		testUtils.assertRepositoryContainsFilesWithContent(repository,
-				"foo/a.txt", "new content of A", "foo/b.txt",
-				"new content of B");
-	}
-
-	@Test
-	public void testCommitIndexSubset() throws Exception {
-		IFile fileA = testUtils.addFileToProject(project.getProject(),
-				"foo/a.txt", "some text");
-		IFile fileB = testUtils.addFileToProject(project.getProject(),
-				"foo/b.txt", "some text");
-		IFile[] filesToCommit = { fileA, fileB };
-		CommitOperation commitOperation = new CommitOperation(filesToCommit,
-				Arrays.asList(filesToCommit), TestUtils.AUTHOR,
-				TestUtils.COMMITTER, "first commit");
-		commitOperation.execute(null);
-		testUtils.changeContentOfFile(project.getProject(), fileA,
-				"new content of A");
-		testUtils.changeContentOfFile(project.getProject(), fileB,
-				"new content of B");
-		resources.add(fileA);
-		resources.add(fileB);
-		new AddToIndexOperation(resources).execute(null);
-		IFile[] filesToCommit2 = { fileA };
-		commitOperation = new CommitOperation(filesToCommit2, EMPTY_FILE_LIST,
-				TestUtils.AUTHOR, TestUtils.COMMITTER, "second commit");
-		commitOperation.execute(null);
-
-		testUtils.assertRepositoryContainsFilesWithContent(repository,
-				"foo/a.txt", "new content of A", "foo/b.txt", "some text");
-	}
-
-	@Test
-	public void testCommitWithStaging() throws Exception {
-		IFile fileA = testUtils.addFileToProject(project.getProject(),
-				"foo/a.txt", "some text");
-		IFile fileB = testUtils.addFileToProject(project.getProject(),
-				"foo/b.txt", "some text");
-		IFile[] filesToCommit = { fileA, fileB };
-		CommitOperation commitOperation = new CommitOperation(filesToCommit,
-				Arrays.asList(filesToCommit), TestUtils.AUTHOR,
-				TestUtils.COMMITTER, "first commit");
-		commitOperation.execute(null);
-
-		testUtils.changeContentOfFile(project.getProject(), fileA,
-				"new content of A");
-		testUtils.changeContentOfFile(project.getProject(), fileB,
-				"new content of B");
-		resources.add(fileA);
-		resources.add(fileB);
-		commitOperation = new CommitOperation(filesToCommit,
-				EMPTY_FILE_LIST, TestUtils.AUTHOR,
-				TestUtils.COMMITTER, "first commit");
-		commitOperation.execute(null);
-
-		testUtils.assertRepositoryContainsFilesWithContent(repository,
-				"foo/a.txt", "new content of A", "foo/b.txt",
-				"new content of B");
-	}
-
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/ConnectProviderOperationTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/ConnectProviderOperationTest.java
deleted file mode 100644
index 0adcdb3..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/ConnectProviderOperationTest.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2007, Robin Rosenberg <robin.rosenberg@dewire.com>
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * Copyright (C) 2013, Matthias Sohn <matthias.sohn@sap.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.test.op;
-
-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.ByteArrayInputStream;
-import java.io.File;
-import java.io.IOException;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.core.runtime.preferences.IEclipsePreferences;
-import org.eclipse.core.runtime.preferences.InstanceScope;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.GitCorePreferences;
-import org.eclipse.egit.core.JobFamilies;
-import org.eclipse.egit.core.RepositoryUtil;
-import org.eclipse.egit.core.op.ConnectProviderOperation;
-import org.eclipse.egit.core.test.GitTestCase;
-import org.eclipse.egit.core.test.TestRepository;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.internal.storage.file.FileRepository;
-import org.eclipse.team.core.RepositoryProvider;
-import org.junit.Test;
-
-public class ConnectProviderOperationTest extends GitTestCase {
-
-	@Test
-	public void testNoRepository() throws CoreException {
-
-		ConnectProviderOperation operation = new ConnectProviderOperation(
-				project.getProject(), new File("../..", Constants.DOT_GIT));
-		operation.execute(null);
-
-		assertFalse(RepositoryProvider.isShared(project.getProject()));
-		assertFalse(gitDir.exists());
-	}
-
-	@Test
-	public void testNewRepository() throws CoreException, IOException {
-
-		Repository repository = new FileRepository(gitDir);
-		repository.create();
-		repository.close();
-		ConnectProviderOperation operation = new ConnectProviderOperation(
-				project.getProject(), gitDir);
-		operation.execute(null);
-
-		assertTrue(RepositoryProvider.isShared(project.getProject()));
-
-		assertTrue(gitDir.exists());
-	}
-
-	@Test
-	public void testAutoIgnoresDerivedFolder() throws Exception {
-		// enable auto-ignore
-		IEclipsePreferences p = InstanceScope.INSTANCE.getNode(Activator
-				.getPluginId());
-		p.putBoolean(GitCorePreferences.core_autoIgnoreDerivedResources, true);
-		Repository repository = new FileRepository(gitDir);
-		repository.create();
-		repository.close();
-		project.setBinFolderDerived();
-		ConnectProviderOperation operation = new ConnectProviderOperation(
-				project.getProject(), gitDir);
-		operation.execute(null);
-
-		assertTrue(RepositoryProvider.isShared(project.getProject()));
-		Job.getJobManager().join(JobFamilies.AUTO_IGNORE, null);
-
-		IPath binPath = project.getProject().getLocation().append("bin");
-		assertTrue(RepositoryUtil.isIgnored(binPath));
-		assertTrue(gitDir.exists());
-		p.putBoolean(GitCorePreferences.core_autoIgnoreDerivedResources, false);
-	}
-
-	@Test
-	public void testNewUnsharedFile() throws CoreException, Exception {
-
-		project.createSourceFolder();
-		IFile fileA = project.getProject().getFolder("src").getFile("A.java");
-		String srcA = "class A {\n" + "}\n";
-		fileA.create(new ByteArrayInputStream(srcA.getBytes("UTF-8")), false,
-				null);
-
-		TestRepository thisGit = new TestRepository(gitDir);
-
-		File committable = new File(fileA.getLocationURI());
-
-		thisGit.addAndCommit(project.project, committable,
-				"testNewUnsharedFile\n\nJunit tests\n");
-
-		assertNull(RepositoryProvider.getProvider(project.getProject()));
-
-		ConnectProviderOperation operation = new ConnectProviderOperation(
-				project.getProject(), gitDir);
-		operation.execute(null);
-
-		assertNotNull(RepositoryProvider.getProvider(project.getProject()));
-	}
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/CreatePatchOperationTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/CreatePatchOperationTest.java
deleted file mode 100644
index c103cef..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/CreatePatchOperationTest.java
+++ /dev/null
@@ -1,350 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2011, Tasktop Technologies
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *    Benjamin Muskalla (Tasktop Technologies) - initial implementation
- *******************************************************************************/
-package org.eclipse.egit.core.test.op;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-import java.io.File;
-
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.core.op.CreatePatchOperation;
-import org.eclipse.egit.core.op.CreatePatchOperation.DiffHeaderFormat;
-import org.eclipse.egit.core.test.GitTestCase;
-import org.eclipse.egit.core.test.TestProject;
-import org.eclipse.egit.core.test.TestRepository;
-import org.eclipse.jgit.diff.DiffFormatter;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.jgit.util.FileUtils;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class CreatePatchOperationTest extends GitTestCase {
-
-	private static final String SIMPLE_GIT_PATCH_CONTENT = "From 6dcd097c7d39e9ba0b31a380981d3fb46017d6c2 Sat, 23 Jul 2011 20:33:24 -0330\n"
-			+ "From: J. Git <j.git@egit.org>\n"
-			+ "Date: Sat, 15 Aug 2009 20:12:58 -0330\n"
-			+ "Subject: [PATCH] 2nd commit\n"
-			+ "\n"
-			+ "diff --git a/test-file b/test-file\n"
-			+ "index e69de29..eb5f2c9 100644\n"
-			+ "--- a/test-file\n"
-			+ "+++ b/test-file\n"
-			+ "@@ -0,0 +1 @@\n"
-			+ "+another line\n"
-			+ "\\ No newline at end of file";
-
-	private static final String SIMPLE_ONELINE_PATCH_CONTENT = "6dcd097c7d39e9ba0b31a380981d3fb46017d6c2 2nd commit\n"
-			+ "diff --git a/test-file b/test-file\n"
-			+ "index e69de29..eb5f2c9 100644\n"
-			+ "--- a/test-file\n"
-			+ "+++ b/test-file\n"
-			+ "@@ -0,0 +1 @@\n"
-			+ "+another line\n"
-			+ "\\ No newline at end of file";
-
-	private static final String SIMPLE_PATCH_CONTENT = "diff --git a/test-file b/test-file\n"
-			+ "index e69de29..eb5f2c9 100644\n"
-			+ "--- a/test-file\n"
-			+ "+++ b/test-file\n"
-			+ "@@ -0,0 +1 @@\n"
-			+ "+another line\n"
-			+ "\\ No newline at end of file";
-
-	private static final String SIMPLE_WORKSPACE_PATCH_CONTENT = "### Eclipse Workspace Patch 1.0\n"
-			+ "#P Project-1\n"
-			+ "diff --git deleted-file deleted-file\n"
-			+ "deleted file mode 100644\n"
-			+ "index e69de29..0000000\n"
-			+ "--- deleted-file\n"
-			+ "+++ /dev/null\n"
-			+ "diff --git new-file new-file\n"
-			+ "new file mode 100644\n"
-			+ "index 0000000..47d2739\n"
-			+ "--- /dev/null\n"
-			+ "+++ new-file\n"
-			+ "@@ -0,0 +1 @@\n"
-			+ "+new content\n"
-			+ "\\ No newline at end of file\n"
-			+ "diff --git test-file test-file\n"
-			+ "index e69de29..eb5f2c9 100644\n"
-			+ "--- test-file\n"
-			+ "+++ test-file\n"
-			+ "@@ -0,0 +1 @@\n"
-			+ "+another line\n"
-			+ "\\ No newline at end of file";
-
-	private RevCommit commit;
-
-	private File file;
-
-	private TestRepository testRepository;
-
-	@Before
-	public void setUp() throws Exception {
-		super.setUp();
-		gitDir = new File(project.getProject().getLocationURI().getPath(),
-				Constants.DOT_GIT);
-		testRepository = new TestRepository(gitDir);
-		testRepository.connect(project.getProject());
-
-		file = testRepository.createFile(project.getProject(), "test-file");
-
-		commit = testRepository.addAndCommit(project.getProject(), file,
-				"new file");
-	}
-
-	@After
-	public void tearDown() throws Exception {
-		testRepository.dispose();
-		super.tearDown();
-	}
-
-	@Test
-	public void testSimpleGitPatch() throws Exception {
-		RevCommit secondCommit = testRepository.appendContentAndCommit(
-				project.getProject(), file, "another line", "2nd commit");
-
-		CreatePatchOperation operation = new CreatePatchOperation(
-				testRepository.getRepository(), secondCommit);
-
-		operation.execute(new NullProgressMonitor());
-
-		String patchContent = operation.getPatchContent();
-		assertNotNull(patchContent);
-		assertGitPatch(SIMPLE_GIT_PATCH_CONTENT, patchContent);
-
-		// repeat setting the header format explicitly
-		operation = new CreatePatchOperation(
-				testRepository.getRepository(), secondCommit);
-
-		operation.setHeaderFormat(DiffHeaderFormat.EMAIL);
-		operation.execute(new NullProgressMonitor());
-
-		patchContent = operation.getPatchContent();
-		assertNotNull(patchContent);
-		assertGitPatch(SIMPLE_GIT_PATCH_CONTENT, patchContent);
-	}
-
-	@Test
-	public void testSimplePatch() throws Exception {
-		RevCommit secondCommit = testRepository.appendContentAndCommit(
-				project.getProject(), file, "another line", "2nd commit");
-
-		CreatePatchOperation operation = new CreatePatchOperation(
-				testRepository.getRepository(), secondCommit);
-
-		operation.setHeaderFormat(DiffHeaderFormat.NONE);
-		operation.execute(new NullProgressMonitor());
-
-		String patchContent = operation.getPatchContent();
-		assertNotNull(patchContent);
-		assertPatch(SIMPLE_PATCH_CONTENT, patchContent);
-	}
-
-	@Test
-	public void testOnelineHeaderPatch() throws Exception {
-		RevCommit secondCommit = testRepository.appendContentAndCommit(
-				project.getProject(), file, "another line", "2nd commit");
-
-		CreatePatchOperation operation = new CreatePatchOperation(
-				testRepository.getRepository(), secondCommit);
-
-		operation.setHeaderFormat(DiffHeaderFormat.ONELINE);
-		operation.execute(new NullProgressMonitor());
-
-		String patchContent = operation.getPatchContent();
-		assertNotNull(patchContent);
-		assertPatch(SIMPLE_ONELINE_PATCH_CONTENT, patchContent);
-	}
-
-	@Test(expected = IllegalStateException.class)
-	public void testFirstCommit() throws Exception {
-		CreatePatchOperation operation = new CreatePatchOperation(
-				testRepository.getRepository(), commit);
-
-		operation.execute(null);
-	}
-
-	@Test
-	public void testNullCommit() throws Exception {
-		new CreatePatchOperation(testRepository.getRepository(), null);
-	}
-
-	@Test(expected = IllegalArgumentException.class)
-	public void testNullRepo() throws Exception {
-		new CreatePatchOperation(null, commit);
-	}
-
-	@Test(expected = IllegalStateException.class)
-	public void testExecuteFirst() throws Exception {
-		CreatePatchOperation operation = new CreatePatchOperation(
-				testRepository.getRepository(), commit);
-		operation.getPatchContent();
-	}
-
-	@Test
-	public void testNullMonitor() throws Exception {
-		RevCommit secondCommit = testRepository.appendContentAndCommit(
-				project.getProject(), file, "another line", "2nd commit");
-		CreatePatchOperation operation = new CreatePatchOperation(
-				testRepository.getRepository(), secondCommit);
-		operation.execute(null);
-	}
-
-	@Test
-	public void testSuggestName() throws Exception {
-		RevCommit aCommit = testRepository.appendContentAndCommit(
-				project.getProject(), file, "another line", "2nd commit");
-		assertEquals("2nd-commit.patch", CreatePatchOperation.suggestFileName(aCommit));
-
-		aCommit = testRepository.appendContentAndCommit(
-				project.getProject(), file, "another line", "[findBugs] Change visibility of repositoryFile to package");
-		assertEquals("findBugs-Change-visibility-of-repositoryFile-to-pack.patch", CreatePatchOperation.suggestFileName(aCommit));
-
-		aCommit = testRepository.appendContentAndCommit(
-				project.getProject(), file, "another line", "Add collapse/expand all utility method for tree viewers.");
-		assertEquals("Add-collapse-expand-all-utility-method-for-tree-view.patch", CreatePatchOperation.suggestFileName(aCommit));
-	}
-
-	@Test
-	public void testComputeWorkspacePath() throws Exception {
-		IPath oldPath = CreatePatchOperation.computeWorkspacePath(new Path(
-				"test-file"), project.getProject());
-		IPath newPath = CreatePatchOperation.computeWorkspacePath(new Path(
-				"test-file"), project.getProject());
-		assertPatch("test-file", oldPath.toString());
-		assertPatch("test-file", newPath.toString());
-	}
-
-	@Test
-	public void testComputeWorkspacePathRepoAboveProject() throws Exception {
-		testRepository.disconnect(project.getProject());
-
-		// new setup
-		project = new TestProject(true, "repo/bundles/Project-1", true, null);
-		File repo = new File(project.getProject().getLocationURI().getPath())
-				.getParentFile().getParentFile();
-		gitDir = new File(repo, Constants.DOT_GIT);
-		testRepository = new TestRepository(gitDir);
-		testRepository.connect(project.getProject());
-
-		IPath oldPath = CreatePatchOperation.computeWorkspacePath(new Path(
-				"bundles/Project-1/test-file"), project.getProject());
-		IPath newPath = CreatePatchOperation.computeWorkspacePath(new Path(
-				"bundles/Project-1/test-file"), project.getProject());
-		assertPatch("test-file", oldPath.toString());
-		assertPatch("test-file", newPath.toString());
-	}
-
-	@Test
-	public void testUpdateWorkspacePatchPrefixes() throws Exception {
-		// setup workspace
-		File newFile = testRepository.createFile(project.getProject(), "new-file");
-		testRepository.appendFileContent(newFile, "new content");
-		File deletedFile = testRepository.createFile(project.getProject(), "deleted-file");
-		commit = testRepository.addAndCommit(project.getProject(), deletedFile,
-				"whatever");
-		FileUtils.delete(deletedFile);
-
-		// unprocessed patch
-		DiffFormatter diffFmt = new DiffFormatter(null);
-		diffFmt.setRepository(testRepository.getRepository());
-		StringBuilder sb = new StringBuilder();
-		sb.append("diff --git a/deleted-file b/deleted-file").append("\n");
-		sb.append("deleted file mode 100644").append("\n");
-		sb.append("index e69de29..0000000").append("\n");
-		sb.append("--- a/deleted-file").append("\n");
-		sb.append("+++ /dev/null").append("\n");
-		sb.append("diff --git a/new-file b/new-file").append("\n");
-		sb.append("new file mode 100644").append("\n");
-		sb.append("index 0000000..47d2739").append("\n");
-		sb.append("--- /dev/null").append("\n");
-		sb.append("+++ b/new-file").append("\n");
-		sb.append("@@ -0,0 +1 @@").append("\n");
-		sb.append("+new content").append("\n");
-		sb.append("\\ No newline at end of file").append("\n");
-		sb.append(SIMPLE_PATCH_CONTENT);
-
-		// update patch
-		CreatePatchOperation op = new CreatePatchOperation(testRepository.getRepository(), null);
-		op.updateWorkspacePatchPrefixes(sb, diffFmt);
-		// add workspace header
-		StringBuilder sb1 = new StringBuilder("### Eclipse Workspace Patch 1.0\n#P ")
-				.append(project.getProject().getName()).append("\n").append(sb);
-
-		assertPatch(SIMPLE_WORKSPACE_PATCH_CONTENT, sb1.toString());
-	}
-
-	@Test
-	public void testWorkspacePatchForCommit() throws Exception {
-		// setup workspace
-		File deletedFile = testRepository.createFile(project.getProject(), "deleted-file");
-		commit = testRepository.addAndCommit(project.getProject(), deletedFile,
-				"whatever");
-		FileUtils.delete(deletedFile);
-		testRepository.appendFileContent(file, "another line");
-		File newFile = testRepository.createFile(project.getProject(), "new-file");
-		testRepository.appendFileContent(newFile, "new content");
-		testRepository.untrack(deletedFile);
-		testRepository.track(file);
-		testRepository.track(newFile);
-		commit = testRepository.commit("2nd commit");
-
-		// create patch
-		CreatePatchOperation operation = new CreatePatchOperation(
-				testRepository.getRepository(), commit);
-
-		operation.setHeaderFormat(DiffHeaderFormat.WORKSPACE);
-		operation.execute(new NullProgressMonitor());
-
-		assertPatch(SIMPLE_WORKSPACE_PATCH_CONTENT, operation.getPatchContent());
-	}
-
-	@Test
-	public void testWorkspacePatchForWorkingDir() throws Exception {
-		// setup workspace
-		testRepository.addToIndex(project.getProject().findMember(".classpath"));
-		testRepository.addToIndex(project.getProject().findMember(".project"));
-		testRepository.commit("commit all");
-		testRepository.appendFileContent(file, "another line");
-		File newFile = testRepository.createFile(project.getProject(), "new-file");
-		testRepository.appendFileContent(newFile, "new content");
-		File deletedFile = testRepository.createFile(project.getProject(), "deleted-file");
-		commit = testRepository.addAndCommit(project.getProject(), deletedFile,
-				"whatever");
-		FileUtils.delete(deletedFile);
-
-		// create patch
-		CreatePatchOperation operation = new CreatePatchOperation(
-				testRepository.getRepository(), null);
-
-		operation.setHeaderFormat(DiffHeaderFormat.WORKSPACE);
-		operation.execute(new NullProgressMonitor());
-
-		assertPatch(SIMPLE_WORKSPACE_PATCH_CONTENT, operation.getPatchContent());
-	}
-
-	private void assertGitPatch(String expected, String actual) {
-		assertEquals(expected.substring(0,45), actual.substring(0,45));
-		assertEquals(expected.substring(expected.indexOf("\n")), actual.substring(actual.indexOf("\n")));
-	}
-
-	private void assertPatch(String expected, String actual) {
-		assertEquals(expected, actual);
-	}
-
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/DeletePathsOperationTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/DeletePathsOperationTest.java
deleted file mode 100644
index f70174d..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/DeletePathsOperationTest.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2012, Robin Stocker <robin@nibor.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.test.op;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-
-import java.io.File;
-import java.util.Arrays;
-import java.util.Collection;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.JobFamilies;
-import org.eclipse.egit.core.internal.indexdiff.IndexDiffCache;
-import org.eclipse.egit.core.internal.indexdiff.IndexDiffCacheEntry;
-import org.eclipse.egit.core.op.DeletePathsOperation;
-import org.eclipse.egit.core.test.DualRepositoryTestCase;
-import org.eclipse.egit.core.test.JobSchedulingAssert;
-import org.eclipse.egit.core.test.TestRepository;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.lib.Repository;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class DeletePathsOperationTest extends DualRepositoryTestCase {
-
-	File workdir;
-
-	IProject project;
-
-	String projectName = "DeletePathsOperationTest";
-
-	@Before
-	public void setUp() throws Exception {
-
-		workdir = testUtils.createTempDir("Repository1");
-
-		repository1 = new TestRepository(new File(workdir, Constants.DOT_GIT));
-		project = testUtils.createProjectInLocalFileSystem(workdir, projectName);
-		repository1.connect(project);
-	}
-
-	@After
-	public void tearDown() throws Exception {
-		Job.getJobManager().join(JobFamilies.INDEX_DIFF_CACHE_UPDATE, null);
-		project.close(null);
-		project.delete(false, false, null);
-		repository1.dispose();
-		repository1 = null;
-		testUtils.deleteTempDirs();
-	}
-
-	@Test
-	public void testDeleteResourceOfProject() throws Exception {
-		IResource resource = testUtils.addFileToProject(project, "file.txt", "Hello world 1");
-
-		deletePaths(Arrays.asList(resource.getLocation()));
-
-		File file = resource.getFullPath().toFile();
-		assertFalse("File should have been deleted", file.exists());
-	}
-
-	@Test
-	public void testDeleteResourceOutsideOfProject() throws Exception {
-		File outsideOfProject = new File(workdir, "outside-of-project.txt");
-		outsideOfProject.createNewFile();
-
-		IPath path = new Path(outsideOfProject.getAbsolutePath());
-
-		// Make sure the cache has at least be refreshed once, otherwise the
-		// assertion at the end is not effective
-		initIndexDiffCache(repository1.getRepository());
-
-		JobSchedulingAssert jobSchedulingAssertion = JobSchedulingAssert
-				.forFamily(JobFamilies.INDEX_DIFF_CACHE_UPDATE);
-		deletePaths(Arrays.asList(path));
-
-		assertFalse("File should have been deleted", outsideOfProject.exists());
-		jobSchedulingAssertion
-				.assertScheduled("Delete of file outside of workspace should have cause an index diff cache job.");
-	}
-
-	private static void initIndexDiffCache(Repository repository)
-			throws Exception {
-		IndexDiffCache cache = Activator.getDefault().getIndexDiffCache();
-		IndexDiffCacheEntry cacheEntry = cache.getIndexDiffCacheEntry(repository);
-		assertNotNull(cacheEntry);
-		Job.getJobManager().join(JobFamilies.INDEX_DIFF_CACHE_UPDATE, null);
-	}
-
-	private void deletePaths(Collection<IPath> paths) throws CoreException {
-		DeletePathsOperation operation = new DeletePathsOperation(paths);
-		operation.execute(null);
-	}
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/DiscardChangesOperationTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/DiscardChangesOperationTest.java
deleted file mode 100644
index c5e6792..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/DiscardChangesOperationTest.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2010, Mathias Kinzler <mathias.kinzler@sap.com>
- * Copyright (C) 2012, Robin Stocker <robin@nibor.org>
- * Copyright (C) 2012, François Rey <eclipse.org_@_francois_._rey_._name>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.test.op;
-
-import static org.junit.Assert.assertEquals;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.core.op.DiscardChangesOperation;
-import org.eclipse.egit.core.test.DualRepositoryTestCase;
-import org.eclipse.egit.core.test.TestRepository;
-import org.eclipse.jgit.lib.Constants;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class DiscardChangesOperationTest extends DualRepositoryTestCase {
-
-	File workdir;
-
-	IProject project;
-	IProject project2;
-
-	String projectName = "DiscardChangesTest";
-
-	@Before
-	public void setUp() throws Exception {
-
-		workdir = testUtils.createTempDir("Repository1");
-
-		repository1 = new TestRepository(new File(workdir, Constants.DOT_GIT));
-
-		// now we create a project in repo1
-		project = testUtils
-				.createProjectInLocalFileSystem(workdir, projectName);
-		testUtils.addFileToProject(project, "folder1/file1.txt", "Hello world 1");
-		testUtils.addFileToProject(project, "folder1/file2.txt", "Hello world 2");
-
-		repository1.connect(project);
-		repository1.trackAllFiles(project);
-		repository1.commit("Initial commit");
-
-		File workdir2 = testUtils.createTempDir("Project2");
-		// Project location is at root of repository
-		project2 = testUtils.createProjectInLocalFileSystem(workdir2.getParentFile(), "Project2");
-		testUtils.addFileToProject(project2, "file.txt", "initial");
-		repository2 = new TestRepository(new File(workdir2, Constants.DOT_GIT));
-		repository2.connect(project2);
-		repository2.trackAllFiles(project2);
-		repository2.commit("Initial commit");
-	}
-
-	@After
-	public void tearDown() throws Exception {
-		project.close(null);
-		project.delete(false, false, null);
-		project2.close(null);
-		project2.delete(false, false, null);
-		repository1.dispose();
-		repository1 = null;
-		repository2.dispose();
-		repository2 = null;
-		testUtils.deleteTempDirs();
-	}
-
-	@Test
-	public void testDiscardChanges() throws Exception {
-		IFile file1 = project.getFile(new Path("folder1/file1.txt"));
-		String contents = testUtils.slurpAndClose(file1.getContents());
-		assertEquals("Hello world 1", contents);
-		setNewFileContent(file1, "changed 1");
-
-		IFile file2 = project.getFile(new Path("folder1/file2.txt"));
-		contents = testUtils.slurpAndClose(file2.getContents());
-		assertEquals("Hello world 2", contents);
-		setNewFileContent(file2, "changed 2");
-
-		DiscardChangesOperation dcop = new DiscardChangesOperation(
-				new IResource[] { file1, file2 });
-		dcop.execute(new NullProgressMonitor());
-
-		contents = testUtils.slurpAndClose(file1.getContents());
-		assertEquals("Hello world 1", contents);
-
-		contents = testUtils.slurpAndClose(file2.getContents());
-		assertEquals("Hello world 2", contents);
-	}
-
-	@Test
-	public void shouldWorkWhenProjectIsRootOfRepository() throws Exception {
-		IFile file = project2.getFile(new Path("file.txt"));
-		String contents = testUtils.slurpAndClose(file.getContents());
-		assertEquals("initial", contents);
-		setNewFileContent(file, "changed");
-
-		DiscardChangesOperation dcop = new DiscardChangesOperation(new IResource[] { project2 });
-		dcop.execute(new NullProgressMonitor());
-
-		String replacedContents = testUtils.slurpAndClose(file.getContents());
-		assertEquals("initial", replacedContents);
-	}
-
-	private void setNewFileContent(IFile file, String content) throws Exception {
-		file.setContents(
-				new ByteArrayInputStream(content.getBytes(project
-						.getDefaultCharset())), 0, null);
-		assertEquals(content, testUtils.slurpAndClose(file.getContents()));
-	}
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/IgnoreOperationTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/IgnoreOperationTest.java
deleted file mode 100644
index 52ccece..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/IgnoreOperationTest.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2010, Benjamin Muskalla <bmuskalla@eclipsesource.com>
- * Copyright (C) 2012, 2013 Robin Stocker <robin@nibor.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.test.op;
-
-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 java.io.ByteArrayInputStream;
-import java.io.File;
-import java.util.Arrays;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IWorkspaceRoot;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.egit.core.op.IgnoreOperation;
-import org.eclipse.egit.core.test.GitTestCase;
-import org.eclipse.egit.core.test.TestRepository;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.util.FileUtils;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class IgnoreOperationTest extends GitTestCase {
-
-	private TestRepository testRepository;
-
-	@Before
-	public void setUp() throws Exception {
-		super.setUp();
-		testRepository = new TestRepository(gitDir);
-		testRepository.connect(project.getProject());
-	}
-
-	@After
-	public void tearDown() throws Exception {
-		testRepository.dispose();
-		// delete gitignore file in workspace folder
-		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
-		File rootFile = root.getRawLocation().toFile();
-		File ignoreFile = new File(rootFile, Constants.GITIGNORE_FILENAME);
-		if (ignoreFile.exists()) {
-			FileUtils.delete(ignoreFile, FileUtils.RETRY);
-			assert !ignoreFile.exists();
-		}
-		super.tearDown();
-	}
-
-	@Test
-	public void testIgnoreFolder() throws Exception {
-		IFolder binFolder = project.getProject().getFolder("bin");
-		IgnoreOperation operation = executeIgnore(binFolder.getLocation());
-
-		String content = project.getFileContent(Constants.GITIGNORE_FILENAME);
-		assertEquals("/bin\n", content);
-		assertFalse(operation.isGitignoreOutsideWSChanged());
-	}
-
-	@Test
-	public void testIgnoreFileCancel() throws Exception {
-		IFolder binFolder = project.getProject().getFolder("bin");
-		IgnoreOperation operation = new IgnoreOperation(Arrays.asList(binFolder.getLocation()));
-		NullProgressMonitor monitor = new NullProgressMonitor();
-		monitor.setCanceled(true);
-		operation.execute(monitor);
-
-		assertFalse(project.getProject().getFile(Constants.GITIGNORE_FILENAME).exists());
-	}
-
-
-	@Test
-	public void testSchedulingRule() throws Exception {
-		IFolder binFolder = project.getProject().getFolder("bin");
-		IgnoreOperation operation = executeIgnore(binFolder.getLocation());
-
-		assertNotNull(operation.getSchedulingRule());
-	}
-
-	@Test
-	public void testIgnoreMultiFile() throws Exception {
-		project.createSourceFolder();
-		IFolder binFolder = project.getProject().getFolder("bin");
-		IFolder srcFolder = project.getProject().getFolder("src");
-		executeIgnore(binFolder.getLocation());
-
-		String content = project.getFileContent(Constants.GITIGNORE_FILENAME);
-		assertEquals("/bin\n", content);
-
-		executeIgnore(srcFolder.getLocation());
-
-		content = project.getFileContent(Constants.GITIGNORE_FILENAME);
-		assertEquals("/bin\n/src\n", content);
-	}
-
-	@Test
-	public void testIgnoreProject() throws Exception {
-		IgnoreOperation operation = executeIgnore(
-				project.getProject().getLocation());
-
-		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
-		File rootFile = root.getRawLocation().toFile();
-		File ignoreFile = new File(rootFile, Constants.GITIGNORE_FILENAME);
-		String content = testUtils.slurpAndClose(ignoreFile.toURI().toURL()
-				.openStream());
-		assertEquals("/" + project.getProject().getName() + "\n", content);
-		assertTrue(operation.isGitignoreOutsideWSChanged());
-	}
-
-	@Test
-	public void testIgnoreNoTrailingNewline() throws Exception {
-		String existing = "/nonewline";
-		IFile ignore = project.getProject().getFile(
-				Constants.GITIGNORE_FILENAME);
-		assertFalse(ignore.exists());
-		ignore.create(new ByteArrayInputStream(existing.getBytes()),
-				IResource.FORCE, new NullProgressMonitor());
-
-		IFolder binFolder = project.getProject().getFolder("bin");
-		IgnoreOperation operation = executeIgnore(binFolder.getLocation());
-
-		String content = project.getFileContent(Constants.GITIGNORE_FILENAME);
-		assertEquals(existing + "\n/bin\n", content);
-		assertFalse(operation.isGitignoreOutsideWSChanged());
-	}
-
-	@Test
-	public void testIgnoreWithResource() throws Exception {
-		IFolder binFolder = project.getProject().getFolder("bin");
-		@SuppressWarnings("deprecation")
-		IgnoreOperation operation = new IgnoreOperation(new IResource[] {binFolder});
-		operation.execute(new NullProgressMonitor());
-
-		String content = project.getFileContent(Constants.GITIGNORE_FILENAME);
-		assertEquals("/bin\n", content);
-	}
-
-	private IgnoreOperation executeIgnore(IPath... paths) throws Exception {
-		IgnoreOperation operation = new IgnoreOperation(Arrays.asList(paths));
-		operation.execute(new NullProgressMonitor());
-		return operation;
-	}
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/ListRemoteOperationTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/ListRemoteOperationTest.java
deleted file mode 100644
index ad3d572..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/ListRemoteOperationTest.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2010, 2012 Mathias Kinzler <mathias.kinzler@sap.com> and others.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.test.op;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
-
-import java.io.File;
-import java.lang.reflect.InvocationTargetException;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.op.CloneOperation;
-import org.eclipse.egit.core.op.ListRemoteOperation;
-import org.eclipse.egit.core.test.DualRepositoryTestCase;
-import org.eclipse.egit.core.test.TestRepository;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.lib.RefUpdate;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.transport.URIish;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class ListRemoteOperationTest extends DualRepositoryTestCase {
-
-	File workdir;
-
-	File workdir2;
-
-	String projectName = "ListRemoteTest";
-
-	/**
-	 * Set up repository1 with branch "master", create some project and commit
-	 * it; then clone into repository2; finally create a branch "test" on top of
-	 * "master" in repository2
-	 *
-	 * @throws Exception
-	 */
-	@Before
-	public void setUp() throws Exception {
-
-		workdir = testUtils.createTempDir("Repository1");
-		workdir2 = testUtils.createTempDir("Repository2");
-
-		repository1 = new TestRepository(new File(workdir, Constants.DOT_GIT));
-
-		// now we create a project in repo1
-		IProject project = testUtils.createProjectInLocalFileSystem(workdir,
-				projectName);
-		testUtils.addFileToProject(project, "folder1/file1.txt", "Hello world");
-
-		repository1.connect(project);
-		repository1.trackAllFiles(project);
-		repository1.commit("Initial commit");
-
-		// let's get rid of the project
-		project.delete(false, false, null);
-
-		// let's clone repository1 to repository2
-		URIish uri = new URIish("file:///"
-				+ repository1.getRepository().getDirectory().toString());
-		CloneOperation clop = new CloneOperation(uri, true, null, workdir2,
-				"refs/heads/master", "origin", 0);
-		clop.run(null);
-
-		Repository existingRepo = Activator
-				.getDefault()
-				.getRepositoryCache()
-				.lookupRepository(
-						new File(workdir2, Constants.DOT_GIT));
-		repository2 = new TestRepository(existingRepo);
-		// we push to branch "test" of repository2
-		RefUpdate createBranch = repository2.getRepository().updateRef(
-				"refs/heads/test");
-		createBranch.setNewObjectId(repository2.getRepository().resolve(
-				"refs/heads/master"));
-		createBranch.update();
-	}
-
-	@After
-	public void tearDown() throws Exception {
-		repository1.dispose();
-		repository2.dispose();
-		testUtils.deleteTempDirs();
-	}
-
-	/**
-	 * List the refs both ways
-	 *
-	 * @throws Exception
-	 */
-	@Test
-	public void testListRemote() throws Exception {
-
-		URIish uri = new URIish("file:///"
-				+ repository2.getRepository().getDirectory().getPath());
-		ListRemoteOperation lrop = new ListRemoteOperation(repository1
-				.getRepository(), uri, 0);
-		lrop.run(null);
-		assertEquals(4, lrop.getRemoteRefs().size());
-		assertNotNull(lrop.getRemoteRef("refs/heads/test"));
-
-		uri = new URIish("file:///"
-				+ repository1.getRepository().getDirectory().getPath());
-		lrop = new ListRemoteOperation(repository2.getRepository(), uri, 0);
-		lrop.run(new NullProgressMonitor());
-		assertEquals(2, lrop.getRemoteRefs().size());
-		assertNotNull(lrop.getRemoteRef("refs/heads/master"));
-	}
-
-	/**
-	 * Call getRemoteRefs without having run the op
-	 *
-	 * @throws Exception
-	 */
-	@Test
-	public void testIllegalStateException() throws Exception {
-
-		URIish uri = new URIish("file:///"
-				+ repository2.getRepository().getDirectory().getPath());
-		ListRemoteOperation lrop = new ListRemoteOperation(repository1
-				.getRepository(), uri, 0);
-		try {
-			lrop.getRemoteRefs();
-			fail("Expected Exception not thrown");
-		} catch (IllegalStateException e) {
-			// expected
-		}
-	}
-
-	/**
-	 * Test with illegal URI
-	 *
-	 * @throws Exception
-	 */
-	@Test
-	public void testIllegalURI() throws Exception {
-
-		URIish uri = new URIish("file:///" + "no/path");
-		ListRemoteOperation lrop = new ListRemoteOperation(repository1
-				.getRepository(), uri, 0);
-		try {
-			lrop.run(new NullProgressMonitor());
-			fail("Expected Exception not thrown");
-		} catch (InvocationTargetException e) {
-			// expected
-		}
-	}
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/MergeOperationTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/MergeOperationTest.java
deleted file mode 100644
index 6af4cd6..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/MergeOperationTest.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2013, Tomasz Zarna <tomasz.zarna@gmail.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.test.op;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Iterator;
-
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.egit.core.op.MergeOperation;
-import org.eclipse.egit.core.test.GitTestCase;
-import org.eclipse.egit.core.test.TestRepository;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.api.LogCommand;
-import org.eclipse.jgit.api.MergeCommand.FastForwardMode;
-import org.eclipse.jgit.api.errors.GitAPIException;
-import org.eclipse.jgit.lib.ConfigConstants;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.lib.StoredConfig;
-import org.eclipse.jgit.revwalk.RevCommit;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class MergeOperationTest extends GitTestCase {
-
-	private static final String MASTER = Constants.R_HEADS +  Constants.MASTER;
-	private static final String SIDE = Constants.R_HEADS + "side";
-
-	private TestRepository testRepository;
-	private RevCommit secondCommit;
-
-	@Before
-	public void setUp() throws Exception {
-		super.setUp();
-		gitDir = new File(project.getProject()
-				.getLocationURI().getPath(), Constants.DOT_GIT);
-		testRepository = new TestRepository(gitDir);
-		testRepository.connect(project.getProject());
-
-		File file1 = testRepository.createFile(project.getProject(), "file1-1");
-		testRepository.addAndCommit(project.getProject(), file1,
-				"master commit 1");
-		testRepository.createBranch(MASTER, SIDE);
-		testRepository.appendFileContent(file1, "file1-2");
-		secondCommit = testRepository.addAndCommit(project.getProject(), file1,
-				"master commit 2");
-		testRepository.checkoutBranch(SIDE);
-	}
-
-	@After
-	public void tearDown() throws Exception {
-		testRepository.dispose();
-		super.tearDown();
-	}
-
-	@Test
-	public void testMergeFF() throws Exception {
-		MergeOperation operation = new MergeOperation(
-				testRepository.getRepository(), MASTER);
-		operation.execute(new NullProgressMonitor());
-
-		assertTrue(testRepository.getRepository().resolve(SIDE).equals(secondCommit));
-		assertEquals(2, countCommitsInHead());
-	}
-
-	@Test
-	public void testMergeoptionsNoFF() throws Exception {
-		setMergeOptions("side", FastForwardMode.NO_FF);
-
-		MergeOperation operation = new MergeOperation(
-				testRepository.getRepository(), MASTER);
-		operation.execute(new NullProgressMonitor());
-
-		assertEquals(3, countCommitsInHead());
-	}
-
-	@Test
-	public void testMergeoptionsFFOnly() throws Exception {
-		setMergeOptions("side", FastForwardMode.FF_ONLY);
-		File file2 = testRepository.createFile(project.getProject(), "file2");
-		testRepository.appendFileContent(file2, "file2-1");
-		RevCommit commit = testRepository.addAndCommit(project.getProject(), file2,
-				"side commit 1");
-
-		MergeOperation operation = new MergeOperation(
-				testRepository.getRepository(), MASTER);
-		operation.execute(new NullProgressMonitor());
-
-		assertTrue(testRepository.getRepository().resolve(SIDE).equals(commit));
-	}
-
-	private void setMergeOptions(String branch, FastForwardMode ffMode)
-			throws IOException {
-		StoredConfig config = testRepository.getRepository().getConfig();
-		config.setEnum(ConfigConstants.CONFIG_BRANCH_SECTION, branch,
-				ConfigConstants.CONFIG_KEY_MERGEOPTIONS, ffMode);
-		config.save();
-	}
-
-	@Test
-	public void testMergeNoFF() throws Exception {
-		setMerge(FastForwardMode.NO_FF);
-
-		MergeOperation operation = new MergeOperation(
-				testRepository.getRepository(), MASTER);
-		operation.execute(new NullProgressMonitor());
-
-		assertEquals(3, countCommitsInHead());
-	}
-
-	@Test
-	public void testMergeFFOnly() throws Exception {
-		setMerge(FastForwardMode.FF_ONLY);
-		File file2 = testRepository.createFile(project.getProject(), "file2");
-		testRepository.appendFileContent(file2, "file2-1");
-		RevCommit commit = testRepository.addAndCommit(project.getProject(), file2,
-				"side commit 1");
-
-		MergeOperation operation = new MergeOperation(
-				testRepository.getRepository(), MASTER);
-		operation.execute(new NullProgressMonitor());
-
-		assertTrue(testRepository.getRepository().resolve(SIDE).equals(commit));
-	}
-
-	private void setMerge(FastForwardMode ffMode) throws IOException {
-		StoredConfig config = testRepository.getRepository().getConfig();
-		config.setEnum(ConfigConstants.CONFIG_KEY_MERGE, null,
-				ConfigConstants.CONFIG_KEY_FF,
-				FastForwardMode.Merge.valueOf(ffMode));
-		config.save();
-	}
-
-	private int countCommitsInHead() throws GitAPIException {
-		LogCommand log = new Git(testRepository.getRepository()).log();
-		Iterable<RevCommit> commits = log.call();
-		int result = 0;
-		for (Iterator i = commits.iterator(); i.hasNext();) {
-			i.next();
-			result++;
-		}
-		return result;
-	}
-}
\ No newline at end of file
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/PushOperationTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/PushOperationTest.java
deleted file mode 100644
index 743cdd6..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/PushOperationTest.java
+++ /dev/null
@@ -1,339 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2010, 2012 Mathias Kinzler <mathias.kinzler@sap.com> and others.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.test.op;
-
-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.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.runtime.ILog;
-import org.eclipse.core.runtime.ILogListener;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.op.AddToIndexOperation;
-import org.eclipse.egit.core.op.BranchOperation;
-import org.eclipse.egit.core.op.CloneOperation;
-import org.eclipse.egit.core.op.CommitOperation;
-import org.eclipse.egit.core.op.PushOperation;
-import org.eclipse.egit.core.op.PushOperationResult;
-import org.eclipse.egit.core.op.PushOperationSpecification;
-import org.eclipse.egit.core.test.DualRepositoryTestCase;
-import org.eclipse.egit.core.test.TestRepository;
-import org.eclipse.egit.core.test.TestUtils;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.RefUpdate;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.jgit.transport.PushResult;
-import org.eclipse.jgit.transport.RemoteRefUpdate;
-import org.eclipse.jgit.transport.RemoteRefUpdate.Status;
-import org.eclipse.jgit.transport.URIish;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class PushOperationTest extends DualRepositoryTestCase {
-
-
-	private static final String INVALID_URI = "invalid-uri";
-
-	File workdir;
-
-	File workdir2;
-
-	String projectName = "PushTest";
-
-	/**
-	 * Set up repository1 with branch "master", create some project and commit
-	 * it; then clone into repository2; finally create a branch "test" on top of
-	 * "master" in repository2
-	 *
-	 * @throws Exception
-	 */
-	@Before
-	public void setUp() throws Exception {
-
-		workdir = testUtils.createTempDir("Repository1");
-		workdir2 = testUtils.createTempDir("Repository2");
-
-		repository1 = new TestRepository(new File(workdir, Constants.DOT_GIT));
-
-		// now we create a project in repo1
-		IProject project = testUtils.createProjectInLocalFileSystem(workdir,
-				projectName);
-		testUtils.addFileToProject(project, "folder1/file1.txt", "Hello world");
-
-		repository1.connect(project);
-		repository1.trackAllFiles(project);
-		repository1.commit("Initial commit");
-
-		// let's get rid of the project
-		project.delete(false, false, null);
-
-		// let's clone repository1 to repository2
-		URIish uri = repository1.getUri();
-		CloneOperation clop = new CloneOperation(uri, true, null, workdir2,
-				"refs/heads/master", "origin", 0);
-		clop.run(null);
-
-		Repository repo2 = Activator.getDefault().getRepositoryCache().lookupRepository(new File(workdir2,
-				Constants.DOT_GIT));
-		repository2 = new TestRepository(repo2);
-		// we push to branch "test" of repository2
-		RefUpdate createBranch = repository2.getRepository().updateRef(
-				"refs/heads/test");
-		createBranch.setNewObjectId(repository2.getRepository().resolve(
-				"refs/heads/master"));
-		createBranch.update();
-	}
-
-	@After
-	public void tearDown() throws Exception {
-		repository1.dispose();
-		repository2.dispose();
-		repository1 = null;
-		repository2 = null;
-		testUtils.deleteTempDirs();
-	}
-
-	/**
-	 * Push from repository1 "master" into "test" of repository2.
-	 *
-	 * @throws Exception
-	 */
-	@Test
-	public void testPush() throws Exception {
-
-		// push from repository1 to repository2
-		PushOperation pop = createPushOperation();
-		pop.run(new NullProgressMonitor());
-		assertEquals(Status.UP_TO_DATE, getStatus(pop.getOperationResult()));
-
-		// let's add a new file to the project shared with repository1
-		IProject proj = importProject(repository1, projectName);
-		ArrayList<IFile> files = new ArrayList<IFile>();
-		IFile newFile = testUtils.addFileToProject(proj, "folder2/file2.txt",
-				"New file");
-		files.add(newFile);
-		IFile[] fileArr = files.toArray(new IFile[files.size()]);
-
-		AddToIndexOperation trop = new AddToIndexOperation(files);
-		trop.execute(null);
-		CommitOperation cop = new CommitOperation(fileArr, files, TestUtils.AUTHOR,
-				TestUtils.COMMITTER, "Added file");
-		cop.execute(null);
-
-		proj.delete(false, false, null);
-
-		pop = createPushOperation();
-		pop.run(null);
-		assertEquals(Status.OK, getStatus(pop.getOperationResult()));
-
-		try {
-			// assert that we can not run this again
-			pop.run(null);
-			fail("Expected Exception not thrown");
-		} catch (IllegalStateException e) {
-			// expected
-		}
-
-		pop = createPushOperation();
-		pop.run(null);
-		assertEquals(Status.UP_TO_DATE, getStatus(pop.getOperationResult()));
-
-		String newFilePath = newFile.getFullPath().toOSString();
-
-		File testFile = new File(workdir2, newFilePath);
-		assertFalse(testFile.exists());
-		testFile = new File(workdir, newFilePath);
-		assertTrue(testFile.exists());
-
-		// check out test and verify the file is there
-		BranchOperation bop = new BranchOperation(repository2.getRepository(),
-				"refs/heads/test");
-		bop.execute(null);
-		testFile = new File(workdir2, newFilePath);
-		assertTrue(testFile.exists());
-	}
-
-	/**
-	 * An invalid URI should yield an operation result with an error message
-	 * and the exception should be logged
-	 *
-	 * @throws Exception
-	 */
-	@Test
-	public void testInvalidUriDuringPush() throws Exception {
-		ILog log = Activator.getDefault().getLog();
-		LogListener listener = new LogListener();
-		log.addLogListener(listener);
-
-		PushOperation pop = createInvalidPushOperation();
-		pop.run(new NullProgressMonitor());
-		PushOperationResult result = pop.getOperationResult();
-		String errorMessage = result.getErrorMessage(new URIish(INVALID_URI));
-		assertNotNull(errorMessage);
-		assertTrue(errorMessage.contains(INVALID_URI));
-
-		assertTrue(listener.loggedSomething());
-		assertTrue(listener.loggedException());
-
-	}
-
-	private PushOperation createInvalidPushOperation() throws Exception {
-		// set up push with invalid URI to provoke an exception
-		PushOperationSpecification spec = new PushOperationSpecification();
-		// the remote is invalid
-		URIish remote = new URIish(INVALID_URI);
-		// update master upon master
-		Repository local = repository1.getRepository();
-		RemoteRefUpdate update = new RemoteRefUpdate(local, "HEAD", "refs/heads/test",
-				false, null, null);
-		spec.addURIRefUpdates(remote, Collections.singletonList(update));
-		// now we can construct the push operation
-		PushOperation pop = new PushOperation(local, spec, false, 0);
-		return pop;
-	}
-
-	private static final class LogListener implements ILogListener {
-		private boolean loggedSomething = false;
-		private boolean loggedException = false;
-
-		public void logging(IStatus status, String plugin) {
-			loggedSomething = true;
-			loggedException = status.getException() != null;
-		}
-
-		public boolean loggedSomething() {
-			return loggedSomething;
-		}
-
-		public boolean loggedException() {
-			return loggedException;
-		}
-
-}
-
-	/**
-	 * We should get an {@link IllegalStateException} if we run
-	 * getOperationResult before run()
-	 *
-	 * @throws Exception
-	 */
-	@Test
-	public void testIllegalStateExceptionOnGetResultWithoutRun()
-			throws Exception {
-		// push from repository1 to repository2
-		PushOperation pop = createPushOperation();
-		try {
-			pop.getOperationResult();
-			fail("Expected Exception not thrown");
-		} catch (IllegalStateException e) {
-			// expected
-		}
-	}
-
-	/**
-	 * We should get an {@link IllegalStateException} if the spec was re-used
-	 *
-	 * @throws Exception
-	 */
-	@Test
-	public void testPushWithReusedSpec() throws Exception {
-
-		PushOperationSpecification spec = new PushOperationSpecification();
-		// the remote is repo2
-		URIish remote = repository2.getUri();
-		// update master upon master
-		List<RemoteRefUpdate> refUpdates = new ArrayList<RemoteRefUpdate>();
-		RemoteRefUpdate update = new RemoteRefUpdate(repository1
-				.getRepository(), "HEAD", "refs/heads/test", false, null, null);
-		refUpdates.add(update);
-		spec.addURIRefUpdates(remote, refUpdates);
-
-		PushOperation pop = new PushOperation(repository1.getRepository(),
-				spec, false, 0);
-		pop.run(null);
-
-		pop = new PushOperation(repository1.getRepository(), spec, false, 0);
-		try {
-			pop.run(null);
-			fail("Expected Exception not thrown");
-		} catch (IllegalStateException e) {
-			// expected
-		}
-	}
-
-	@Test
-	public void testUpdateTrackingBranchIfSpecifiedInRemoteRefUpdate() throws Exception {
-		// Commit on repository 2
-		IProject project = importProject(repository2, projectName);
-		RevCommit commit = repository2.addAndCommit(project, new File(workdir2, "test.txt"), "Commit in repository 2");
-		project.delete(false, false, null);
-
-		// We want to push from repository 2 to 1 (because repository 2 already
-		// has tracking set up)
-		URIish remote = repository1.getUri();
-		String trackingRef = "refs/remotes/origin/master";
-		RemoteRefUpdate update = new RemoteRefUpdate(
-				repository2.getRepository(), "HEAD", "refs/heads/master", false,
-				trackingRef, null);
-		PushOperationSpecification spec = new PushOperationSpecification();
-		spec.addURIRefUpdates(remote, Arrays.asList(update));
-
-		PushOperation push = new PushOperation(repository2.getRepository(),
-				spec, false, 0);
-		push.run(null);
-
-		PushOperationResult result = push.getOperationResult();
-		PushResult pushResult = result.getPushResult(remote);
-		assertNotNull("Expected result to have tracking ref update", pushResult.getTrackingRefUpdate(trackingRef));
-
-		ObjectId trackingId = repository2.getRepository().resolve(trackingRef);
-		assertEquals("Expected tracking branch to be updated", commit.getId(), trackingId);
-	}
-
-	private Status getStatus(PushOperationResult operationResult) {
-		URIish uri = operationResult.getURIs().iterator().next();
-		return operationResult.getPushResult(uri).getRemoteUpdates().iterator()
-				.next().getStatus();
-	}
-
-	private PushOperation createPushOperation() throws Exception {
-		// set up push from repository1 to repository2
-		// we can not re-use the RemoteRefUpdate!!!
-		PushOperationSpecification spec = new PushOperationSpecification();
-		// the remote is repo2
-		URIish remote = new URIish("file:///"
-				+ repository2.getRepository().getDirectory().toString());
-		// update master upon master
-		List<RemoteRefUpdate> refUpdates = new ArrayList<RemoteRefUpdate>();
-		RemoteRefUpdate update = new RemoteRefUpdate(repository1
-				.getRepository(), "HEAD", "refs/heads/test", false, null, null);
-		refUpdates.add(update);
-		spec.addURIRefUpdates(remote, refUpdates);
-		// now we can construct the push operation
-		PushOperation pop = new PushOperation(repository1.getRepository(),
-				spec, false, 0);
-		return pop;
-	}
-
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/RebaseOperationTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/RebaseOperationTest.java
deleted file mode 100644
index 86fbb9c..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/RebaseOperationTest.java
+++ /dev/null
@@ -1,238 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2010, Mathias Kinzler <mathias.kinzler@sap.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.test.op;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.egit.core.op.RebaseOperation;
-import org.eclipse.egit.core.test.GitTestCase;
-import org.eclipse.egit.core.test.TestRepository;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.api.RebaseResult;
-import org.eclipse.jgit.api.RebaseCommand.Operation;
-import org.eclipse.jgit.api.RebaseResult.Status;
-import org.eclipse.jgit.api.errors.WrongRepositoryStateException;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.jgit.revwalk.RevWalk;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-
-public class RebaseOperationTest extends GitTestCase {
-
-	private static final String TOPIC = Constants.R_HEADS + "topic";
-
-	private static final String MASTER = Constants.R_HEADS + "master";
-
-	TestRepository testRepository;
-
-	Repository repository;
-
-	Git git;
-
-	@Before
-	public void setUp() throws Exception {
-		super.setUp();
-		testRepository = new TestRepository(gitDir);
-		repository = testRepository.getRepository();
-		// create first commit containing a dummy file
-		testRepository
-				.createInitialCommit("testRebaseOperation\n\nfirst commit\n");
-		git = new Git(repository);
-	}
-
-	@Test
-	@Ignore
-	// currently not working as expected; see also TODO in RebaseCommand
-	public void testUpToDate() throws Exception {
-		IFile file = project.createFile("theFile.txt", "Hello, world"
-				.getBytes("UTF-8"));
-		// first commit in master: add theFile.txt
-		RevCommit first = testRepository.addAndCommit(project.project,
-				new File(file.getLocationURI()), "Adding theFile.txt");
-
-		testRepository.createBranch(MASTER, TOPIC);
-
-		// checkout topic
-		testRepository.checkoutBranch(TOPIC);
-
-		file = project.createFile("theSecondFile.txt", "Hello, world"
-				.getBytes("UTF-8"));
-		// topic commit: add second file
-		RevCommit topicCommit = testRepository.addAndCommit(project.project,
-				new File(file.getLocationURI()), "Adding theSecondFile.txt");
-
-		// parent of topic commit should be first master commit before rebase
-		assertEquals(first, topicCommit.getParent(0));
-
-		// rebase topic onto master
-		RebaseOperation op = new RebaseOperation(
-				testRepository.getRepository(), testRepository.getRepository()
-						.getRef(MASTER));
-		op.execute(null);
-
-		RebaseResult res = op.getResult();
-		assertEquals(RebaseResult.Status.UP_TO_DATE, res.getStatus());
-
-		RevCommit newTopic = new RevWalk(repository).parseCommit(repository
-				.resolve(TOPIC));
-		assertEquals(topicCommit, newTopic);
-		assertEquals(first, newTopic.getParent(0));
-	}
-
-	@Test
-	public void testNoConflict() throws Exception {
-		IFile file = project.createFile("theFile.txt", "Hello, world"
-				.getBytes("UTF-8"));
-		// first commit in master: add theFile.txt
-		RevCommit first = testRepository.addAndCommit(project.project,
-				new File(file.getLocationURI()), "Adding theFile.txt");
-
-		testRepository.createBranch(MASTER, TOPIC);
-
-		file.setContents(new ByteArrayInputStream("master".getBytes("UTF-8")),
-				0, null);
-		// second commit in master: modify theFile.txt
-		RevCommit second = git.commit().setAll(true).setMessage(
-				"Modify theFile.txt").call();
-		assertEquals(first, second.getParent(0));
-
-		// checkout topic
-		testRepository.checkoutBranch(TOPIC);
-
-		file = project.createFile("theSecondFile.txt", "Hello, world"
-				.getBytes("UTF-8"));
-		// topic commit: add second file
-		RevCommit topicCommit = testRepository.addAndCommit(project.project,
-				new File(file.getLocationURI()), "Adding theSecondFile.txt");
-
-		// parent of topic commit should be first master commit before rebase
-		assertEquals(first, topicCommit.getParent(0));
-
-		// rebase topic onto master
-		RebaseOperation op = new RebaseOperation(
-				testRepository.getRepository(), testRepository.getRepository()
-						.getRef(MASTER));
-		op.execute(null);
-
-		RebaseResult res = op.getResult();
-		assertEquals(RebaseResult.Status.OK, res.getStatus());
-
-		RevCommit newTopic = new RevWalk(repository).parseCommit(repository
-				.resolve(TOPIC));
-		assertEquals(second, newTopic.getParent(0));
-	}
-
-	@Test
-	public void testStopAndAbortOnConflict() throws Exception {
-		IFile file = project.createFile("theFile.txt", "Hello, world"
-				.getBytes("UTF-8"));
-		// first commit in master: add theFile.txt
-		RevCommit first = testRepository.addAndCommit(project.project,
-				new File(file.getLocationURI()), "Adding theFile.txt");
-
-		testRepository.createBranch(MASTER, TOPIC);
-
-		file.setContents(new ByteArrayInputStream("master".getBytes("UTF-8")),
-				0, null);
-		// second commit in master: modify theFile.txt
-		RevCommit second = git.commit().setAll(true).setMessage(
-				"Modify theFile.txt").call();
-		assertEquals(first, second.getParent(0));
-
-		// checkout topic
-		testRepository.checkoutBranch(TOPIC);
-
-		// set conflicting content in topic
-		file.setContents(new ByteArrayInputStream("topic".getBytes("UTF-8")),
-				0, null);
-		// topic commit: add second file
-		RevCommit topicCommit = testRepository.addAndCommit(project.project,
-				new File(file.getLocationURI()), "Changing theFile.txt again");
-
-		// parent of topic commit should be first master commit before rebase
-		assertEquals(first, topicCommit.getParent(0));
-
-		// rebase topic onto master
-		RebaseOperation op = new RebaseOperation(
-				testRepository.getRepository(), testRepository.getRepository()
-						.getRef(MASTER));
-		op.execute(null);
-
-		RebaseResult res = op.getResult();
-		assertEquals(RebaseResult.Status.STOPPED, res.getStatus());
-
-		// let's try to abort this here
-		RebaseOperation abort = new RebaseOperation(repository, Operation.ABORT);
-		abort.execute(null);
-		RebaseResult abortResult = abort.getResult();
-		assertEquals(Status.ABORTED, abortResult.getStatus());
-
-		assertEquals(topicCommit, repository.resolve(Constants.HEAD));
-	}
-
-	@Test
-	public void testExceptionWhenRestartingStoppedRebase() throws Exception {
-		IFile file = project.createFile("theFile.txt", "Hello, world"
-				.getBytes("UTF-8"));
-		// first commit in master: add theFile.txt
-		RevCommit first = testRepository.addAndCommit(project.project,
-				new File(file.getLocationURI()), "Adding theFile.txt");
-
-		testRepository.createBranch(MASTER, TOPIC);
-
-		file.setContents(new ByteArrayInputStream("master".getBytes("UTF-8")),
-				0, null);
-		// second commit in master: modify theFile.txt
-		RevCommit second = git.commit().setAll(true).setMessage(
-				"Modify theFile.txt").call();
-		assertEquals(first, second.getParent(0));
-
-		// checkout topic
-		testRepository.checkoutBranch(TOPIC);
-
-		// set conflicting content in topic
-		file.setContents(new ByteArrayInputStream("topic".getBytes("UTF-8")),
-				0, null);
-		// topic commit: add second file
-		RevCommit topicCommit = testRepository.addAndCommit(project.project,
-				new File(file.getLocationURI()), "Changing theFile.txt again");
-
-		// parent of topic commit should be first master commit before rebase
-		assertEquals(first, topicCommit.getParent(0));
-
-		// rebase topic onto master
-		RebaseOperation op = new RebaseOperation(repository, repository
-				.getRef(MASTER));
-		op.execute(null);
-
-		RebaseResult res = op.getResult();
-		assertEquals(RebaseResult.Status.STOPPED, res.getStatus());
-
-		try {
-			// let's try to start again, we should get a wrapped
-			// WrongRepositoryStateException
-			op = new RebaseOperation(repository, repository.getRef(MASTER));
-			op.execute(null);
-			fail("Expected Exception not thrown");
-		} catch (CoreException e) {
-			Throwable cause = e.getCause();
-			assertTrue(cause instanceof WrongRepositoryStateException);
-		}
-	}
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/RemoveFromIndexOperationTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/RemoveFromIndexOperationTest.java
deleted file mode 100644
index 63b02a1..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/RemoveFromIndexOperationTest.java
+++ /dev/null
@@ -1,221 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2010, Stefan Lay <stefan.lay@sap.com>
- * Copyright (C) 2011, Dariusz Luksza <dariusz@luksza.org>
- * Copyright (C) 2012, Robin Stocker <robin@nibor.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.test.op;
-
-import static java.util.Arrays.asList;
-import static junit.framework.Assert.assertTrue;
-import static org.junit.Assert.assertFalse;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.util.Arrays;
-import java.util.List;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.egit.core.op.AddToIndexOperation;
-import org.eclipse.egit.core.op.RemoveFromIndexOperation;
-import org.eclipse.egit.core.test.GitTestCase;
-import org.eclipse.egit.core.test.TestProject;
-import org.eclipse.egit.core.test.TestRepository;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.util.FileUtils;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-// based on AddOperationTest
-public class RemoveFromIndexOperationTest extends GitTestCase {
-
-	private TestRepository testRepo;
-
-	private File gitDir2;
-	private TestRepository testRepo2;
-	private TestProject project2;
-
-	@Before
-	public void setUp() throws Exception {
-		super.setUp();
-		gitDir = new File(project.getProject()
-				.getLocationURI().getPath(), Constants.DOT_GIT);
-		testRepo = new TestRepository(gitDir);
-		testRepo.connect(project.getProject());
-		testRepo.commit("initial commit");
-
-		project2 = new TestProject(true, "Project-2");
-		gitDir2 = new File(project2.getProject()
-				.getLocationURI().getPath(), Constants.DOT_GIT);
-		testRepo2 = new TestRepository(gitDir2);
-		testRepo2.connect(project2.getProject());
-		testRepo2.commit("initial commit repo 2");
-	}
-
-	@After
-	public void tearDown() throws Exception {
-		testRepo.dispose();
-		testRepo2.dispose();
-		project2.dispose();
-		if (gitDir2.exists())
-			FileUtils.delete(gitDir2, FileUtils.RECURSIVE | FileUtils.RETRY);
-		super.tearDown();
-	}
-
-	@Test
-	public void shouldUnTrackFile() throws Exception {
-		// given
-		IFile file1 = createFileInRepo("a.txt");
-		new AddToIndexOperation(asList(file1)).execute(null);
-
-		// when
-		new RemoveFromIndexOperation(Arrays.asList(file1.getLocation())).execute(null);
-
-		// then
-		assertTrue(testRepo.removedFromIndex(file1.getLocation()
-				.toPortableString()));
-	}
-
-	@Test
-	public void shouldUnTrackFilesInFolder() throws Exception {
-		// given
-		IFile file1 = createFileInRepo("sub/a.txt");
-		IFile file2 = createFileInRepo("sub/b.txt");
-		IFolder container = project.getProject().getFolder("sub");
-		new AddToIndexOperation(asList(file1, file2)).execute(null);
-
-		// when
-		new RemoveFromIndexOperation(asList(container.getLocation())).execute(null);
-
-		// then
-		assertTrue(testRepo.removedFromIndex(file1.getLocation().toPortableString()));
-		assertTrue(testRepo.removedFromIndex(file2.getLocation().toPortableString()));
-	}
-
-	@Test
-	public void shouldUnstExistingFile() throws Exception {
-		// given
-		IFile file1 = createFileInRepo("a.txt");
-		new AddToIndexOperation(asList(file1)).execute(null);
-
-		testRepo.commit("first commit");
-
-		Thread.sleep(1000);
-		file1.setContents(
-				new ByteArrayInputStream("other text".getBytes(project.project
-						.getDefaultCharset())), 0, null);
-		new AddToIndexOperation(asList(file1)).execute(null);
-
-		// when
-		new RemoveFromIndexOperation(asList(file1.getLocation())).execute(null);
-
-		// then
-		assertTrue(testRepo.removedFromIndex(file1.getLocation().toPortableString()));
-	}
-
-	@Test
-	public void shouldUnstageFilesInFolder() throws Exception {
-		// given
-		IFile file1 = createFileInRepo("sub/a.txt");
-		IFile file2 = createFileInRepo("sub/b.txt");
-		IFolder container = project.getProject().getFolder("sub");
-		List<IFolder> addResources = asList(project.getProject().getFolder("sub"));
-		new AddToIndexOperation(addResources).execute(null);
-
-		testRepo.commit("first commit");
-
-		Thread.sleep(1000);
-
-		file1.setContents(
-				new ByteArrayInputStream("other text".getBytes(project.project
-						.getDefaultCharset())), 0, null);
-		file2.setContents(
-				new ByteArrayInputStream("other text".getBytes(project.project
-						.getDefaultCharset())), 0, null);
-		new AddToIndexOperation(addResources).execute(null);
-
-		// when
-		new RemoveFromIndexOperation(asList(container.getLocation())).execute(null);
-
-		// then
-		assertTrue(testRepo.removedFromIndex(file1.getLocation().toPortableString()));
-		assertTrue(testRepo.removedFromIndex(file2.getLocation().toPortableString()));
-	}
-
-	@Test
-	public void shouldUnstageFilesInNestedFolder() throws Exception {
-		// given
-		IFile file1 = createFileInRepo("sub/next/a.txt");
-		IFile file2 = createFileInRepo("sub/next/b.txt");
-		IFolder container = project.getProject().getFolder("sub");
-		List<IFolder> addResources = asList(project.getProject().getFolder("sub"));
-		new AddToIndexOperation(addResources).execute(null);
-
-		testRepo.commit("first commit");
-
-		Thread.sleep(1000);
-
-		file1.setContents(
-				new ByteArrayInputStream("other text".getBytes(project.project
-						.getDefaultCharset())), 0, null);
-		file2.setContents(
-				new ByteArrayInputStream("other text".getBytes(project.project
-						.getDefaultCharset())), 0, null);
-		new AddToIndexOperation(addResources).execute(null);
-
-		// when
-		new RemoveFromIndexOperation(asList(container.getLocation())).execute(null);
-
-		// then
-		assertTrue(testRepo.removedFromIndex(file1.getLocation().toPortableString()));
-		assertTrue(testRepo.removedFromIndex(file2.getLocation().toPortableString()));
-	}
-
-	@Test
-	public void shouldUnstageFilesFromMultipleRepositories() throws Exception {
-		// given
-		IFile fileRepo1 = testUtils.addFileToProject(project.getProject(), "1.txt", "content");
-		IFile fileRepo2 = testUtils.addFileToProject(project2.getProject(), "2.txt", "content");
-		new AddToIndexOperation(asList(fileRepo1)).execute(null);
-		new AddToIndexOperation(asList(fileRepo2)).execute(null);
-
-		// when
-		new RemoveFromIndexOperation(Arrays.asList(fileRepo1.getLocation(), fileRepo2.getLocation())).execute(null);
-
-		// then
-		assertTrue(testRepo.removedFromIndex(fileRepo1.getLocation()
-				.toPortableString()));
-		assertTrue(testRepo.removedFromIndex(fileRepo2.getLocation()
-				.toPortableString()));
-	}
-
-	@Test
-	public void shouldRemoveFromIndexOnInitialCommit() throws Exception {
-		testRepo.dispose();
-		FileUtils.delete(gitDir, FileUtils.RECURSIVE | FileUtils.RETRY);
-		testRepo = new TestRepository(gitDir);
-		testRepo.connect(project.getProject());
-
-		IFile file = testUtils.addFileToProject(project.getProject(), "file.txt", "content");
-		new AddToIndexOperation(asList(file)).execute(null);
-
-		assertTrue(testRepo.inIndex(file.getLocation().toString()));
-
-		new RemoveFromIndexOperation(Arrays.asList(file.getLocation())).execute(null);
-
-		assertFalse(testRepo.inIndex(file.getLocation().toString()));
-		assertTrue(file.getLocation().toFile().exists());
-	}
-
-	private IFile createFileInRepo(String fileName) throws Exception {
-		return testUtils.addFileToProject(project.getProject(), fileName,
-				"some text");
-	}
-
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/ResetOperationTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/ResetOperationTest.java
deleted file mode 100644
index 2f6bc74..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/ResetOperationTest.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2010, Jens Baumgart <jens.baumgart@sap.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.test.op;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.InputStream;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.egit.core.op.ResetOperation;
-import org.eclipse.egit.core.test.GitTestCase;
-import org.eclipse.egit.core.test.TestRepository;
-import org.eclipse.jgit.api.ResetCommand.ResetType;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.revwalk.RevCommit;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class ResetOperationTest extends GitTestCase {
-
-	TestRepository testRepository;
-
-	Repository repository;
-
-	// members filled by setupRepository()
-	RevCommit initialCommit;
-
-	File projectFile;
-
-	IFile untrackedFile;
-
-	IFile fileInIndex;
-
-	@Before
-	public void setUp() throws Exception {
-		super.setUp();
-		testRepository = new TestRepository(gitDir);
-		repository = testRepository.getRepository();
-	}
-
-	@After
-	public void tearDown() throws Exception {
-		testRepository.dispose();
-		repository = null;
-		super.tearDown();
-	}
-
-	@Test
-	public void testHardReset() throws Exception {
-		setupRepository();
-		String fileInIndexPath = fileInIndex.getLocation().toPortableString();
-		new ResetOperation(repository, initialCommit.getName(), ResetType.HARD)
-				.execute(null);
-		// .project must disappear, related Eclipse project must be deleted
-		assertFalse(projectFile.exists());
-		assertFalse(project.getProject().exists());
-		// check if HEAD points to initial commit now
-		assertTrue(repository.resolve("HEAD").equals(initialCommit));
-		// check if files were removed
-		assertFalse(untrackedFile.exists());
-		assertFalse(fileInIndex.exists());
-		// fileInIndex must no longer be in HEAD and in the index
-		assertFalse(testRepository.inHead(fileInIndexPath));
-		assertFalse(testRepository.inIndex(fileInIndexPath));
-	}
-
-	@Test
-	public void testSoftReset() throws Exception {
-		setupRepository();
-		String fileInIndexPath = fileInIndex.getLocation().toPortableString();
-		new ResetOperation(repository, initialCommit.getName(), ResetType.SOFT)
-				.execute(null);
-		// .project must remain
-		assertTrue(projectFile.exists());
-		assertTrue(project.getProject().exists());
-		// check if HEAD points to initial commit now
-		assertTrue(repository.resolve("HEAD").equals(initialCommit));
-		// untrackedFile and fileInIndex must still exist
-		assertTrue(untrackedFile.exists());
-		assertTrue(fileInIndex.exists());
-		// fileInIndex must no longer be in HEAD
-		assertFalse(testRepository.inHead(fileInIndexPath));
-		// fileInIndex must exist in the index
-		assertTrue(testRepository.inIndex(fileInIndexPath));
-	}
-
-	@Test
-	public void testMixedReset() throws Exception {
-		setupRepository();
-		String fileInIndexPath = fileInIndex.getLocation().toPortableString();
-		new ResetOperation(repository, initialCommit.getName(), ResetType.MIXED)
-				.execute(null);
-		// .project must remain
-		assertTrue(projectFile.exists());
-		assertTrue(project.getProject().exists());
-		// check if HEAD points to initial commit now
-		assertTrue(repository.resolve("HEAD").equals(initialCommit));
-		// untrackedFile and fileInIndex must still exist
-		assertTrue(untrackedFile.exists());
-		assertTrue(fileInIndex.exists());
-		// fileInIndex must no longer be in HEAD
-		assertFalse(testRepository.inHead(fileInIndexPath));
-		// fileInIndex must not in the index
-		assertFalse(testRepository.inIndex(fileInIndexPath));
-	}
-
-	private void setupRepository() throws Exception {
-		// create first commit containing a dummy file
-		initialCommit = testRepository
-				.createInitialCommit("testResetOperation\n\nfirst commit\n");
-		// add .project to version control
-		String path = project.getProject().getLocation().append(".project")
-				.toOSString();
-		projectFile = new File(path);
-		testRepository.track(projectFile);
-		// add fileInIndex to version control
-		fileInIndex = createFile("fileInIndex");
-		testRepository.track(new File(fileInIndex.getLocation().toOSString()));
-		testRepository.commit("Add .project file");
-		// modify fileInIndex and add it to the index
-		InputStream stream = new ByteArrayInputStream(new byte[] { 'I', 'n',
-				'd', 'e', 'x' });
-		fileInIndex.setContents(stream, 0, null);
-		testRepository.addToIndex(fileInIndex);
-		// create an untracked file
-		untrackedFile = createFile("untrackedFile");
-	}
-
-	/**
-	 * create a file with the given name in the root folder of testproject
-	 *
-	 * @param name
-	 *            name of file
-	 * @return new file
-	 * @throws CoreException
-	 */
-	private IFile createFile(String name) throws CoreException {
-		IFile file = project.project.getFile(name);
-		file.create(
-				new ByteArrayInputStream(new byte[] { 'T', 'e', 's', 't' }),
-				true, null);
-		return file;
-	}
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/StashCreateOperationTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/StashCreateOperationTest.java
deleted file mode 100644
index 47a1608..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/StashCreateOperationTest.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2012, Maik Schreiber <blizzy@blizzy.de>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-
-package org.eclipse.egit.core.test.op;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.io.File;
-
-import org.eclipse.egit.core.op.StashCreateOperation;
-import org.eclipse.egit.core.test.GitTestCase;
-import org.eclipse.egit.core.test.TestRepository;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.jgit.revwalk.RevWalk;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class StashCreateOperationTest extends GitTestCase {
-
-	TestRepository testRepository;
-
-	Repository repository;
-
-	@Before
-	public void setUp() throws Exception {
-		super.setUp();
-		gitDir = new File(project.getProject()
-				.getLocationURI().getPath(), Constants.DOT_GIT);
-		testRepository = new TestRepository(gitDir);
-		repository = testRepository.getRepository();
-		testRepository.connect(project.getProject());
-		testRepository.commit("initial commit");
-	}
-
-	@After
-	public void tearDown() throws Exception {
-		testRepository.dispose();
-		repository = null;
-		super.tearDown();
-	}
-
-	@Test
-	public void testDefaultMessage() throws Exception {
-		testUtils.addFileToProject(project.getProject(), "foo/a.txt", "some text");
-		StashCreateOperation stashCreateOperation = new StashCreateOperation(repository);
-		stashCreateOperation.execute(null);
-
-		RevWalk revWalk = new RevWalk(repository);
-		RevCommit commit = revWalk.parseCommit(repository.resolve("stash@{0}"));
-		assertTrue(commit.getFullMessage().length() > 0);
-	}
-
-	@Test
-	public void testCustomMessage() throws Exception {
-		testUtils.addFileToProject(project.getProject(), "foo/a.txt", "some text");
-		String message = "stash message";
-		StashCreateOperation stashCreateOperation = new StashCreateOperation(repository, message);
-		stashCreateOperation.execute(null);
-
-		RevWalk revWalk = new RevWalk(repository);
-		RevCommit commit = revWalk.parseCommit(repository.resolve("stash@{0}"));
-		assertEquals(message, commit.getFullMessage());
-	}
-
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/TagOperationTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/TagOperationTest.java
deleted file mode 100644
index e5f633e..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/TagOperationTest.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2010, 2012 Chris Aniszczyk <caniszczyk@gmail.com> and others.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.test.op;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.io.File;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.egit.core.op.TagOperation;
-import org.eclipse.egit.core.test.DualRepositoryTestCase;
-import org.eclipse.egit.core.test.TestRepository;
-import org.eclipse.egit.core.test.TestUtils;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.lib.TagBuilder;
-import org.eclipse.jgit.revwalk.RevTag;
-import org.eclipse.jgit.revwalk.RevWalk;
-import org.eclipse.jgit.util.RawParseUtils;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class TagOperationTest extends DualRepositoryTestCase {
-
-	File workdir;
-
-	String projectName = "TagTest";
-
-	IProject project;
-
-	@Before
-	public void setUp() throws Exception {
-
-		workdir = testUtils.createTempDir("Repository1");
-
-		repository1 = new TestRepository(new File(workdir, Constants.DOT_GIT));
-
-		project = testUtils.createProjectInLocalFileSystem(workdir,
-				projectName);
-		testUtils.addFileToProject(project, "folder1/file1.txt", "Hello world");
-
-		repository1.connect(project);
-		repository1.trackAllFiles(project);
-		repository1.commit("Initial commit");
-	}
-
-	@After
-	public void tearDown() throws Exception {
-		project.close(null);
-		project.delete(false, false, null);
-		repository1.dispose();
-		repository1 = null;
-		testUtils.deleteTempDirs();
-	}
-
-	@Test
-	public void addTag() throws Exception {
-		assertTrue("Tags should be empty", repository1.getRepository()
-				.getTags().isEmpty());
-		TagBuilder newTag = new TagBuilder();
-		newTag.setTag("TheNewTag");
-		newTag.setMessage("Well, I'm the tag");
-		newTag.setTagger(RawParseUtils.parsePersonIdent(TestUtils.AUTHOR));
-		newTag.setObjectId(repository1.getRepository()
-				.resolve("refs/heads/master"), Constants.OBJ_COMMIT);
-		TagOperation top = new TagOperation(repository1.getRepository(),
-				newTag, false);
-		top.execute(new NullProgressMonitor());
-		assertFalse("Tags should not be empty", repository1.getRepository()
-				.getTags().isEmpty());
-
-		try {
-			top.execute(null);
-			fail("Expected Exception not thrown");
-		} catch (CoreException e) {
-			// expected
-		}
-
-		top = new TagOperation(repository1.getRepository(), newTag, true);
-		try {
-			top.execute(null);
-			fail("Expected Exception not thrown");
-		} catch (CoreException e) {
-			// expected
-		}
-		Ref tagRef = repository1.getRepository().getTags().get("TheNewTag");
-		RevWalk walk = new RevWalk(repository1.getRepository());
-		RevTag tag = walk.parseTag(
-				repository1.getRepository().resolve(tagRef.getName()));
-
-		newTag.setMessage("Another message");
-		assertFalse("Messages should differ", tag.getFullMessage().equals(
-				newTag.getMessage()));
-		top.execute(null);
-		tag = walk.parseTag(
-				repository1.getRepository().resolve(tagRef.getName()));
-		assertTrue("Messages be same", tag.getFullMessage().equals(
-				newTag.getMessage()));
-	}
-
-}
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/TrackUntrackOperationTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/TrackUntrackOperationTest.java
deleted file mode 100644
index 7643d28..0000000
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/test/op/TrackUntrackOperationTest.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2010, Mathias Kinzler <mathias.kinzler@sap.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.test.op;
-
-import static org.junit.Assert.assertEquals;
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IResourceVisitor;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.egit.core.op.AddToIndexOperation;
-import org.eclipse.egit.core.op.UntrackOperation;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.core.test.DualRepositoryTestCase;
-import org.eclipse.egit.core.test.TestRepository;
-import org.eclipse.jgit.dircache.DirCache;
-import org.eclipse.jgit.lib.Constants;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class TrackUntrackOperationTest extends DualRepositoryTestCase {
-
-	File workdir;
-
-	IProject project;
-
-	String projectName = "TrackTest";
-
-	@Before
-	public void setUp() throws Exception {
-
-		workdir = testUtils.createTempDir("Repository1");
-
-		repository1 = new TestRepository(new File(workdir, Constants.DOT_GIT));
-
-		// now we create a project in repo1
-		project = testUtils
-				.createProjectInLocalFileSystem(workdir, projectName);
-		testUtils.addFileToProject(project, "folder1/file1.txt", "Hello world");
-
-		repository1.connect(project);
-	}
-
-	@After
-	public void tearDown() throws Exception {
-		project.close(null);
-		project.delete(false, false, null);
-		repository1.dispose();
-		repository1 = null;
-		testUtils.deleteTempDirs();
-	}
-
-	@Test
-	public void testTrackFiles() throws Exception {
-
-		final ArrayList<IFile> files = new ArrayList<IFile>();
-
-		project.accept(new IResourceVisitor() {
-
-			public boolean visit(IResource resource) throws CoreException {
-				if (resource instanceof IFile)
-					files.add((IFile) resource);
-				return true;
-			}
-		});
-
-		IFile[] fileArr = files.toArray(new IFile[files.size()]);
-
-		assertTrackedState(fileArr, false);
-
-		AddToIndexOperation trop = new AddToIndexOperation(files);
-		trop.execute(new NullProgressMonitor());
-
-		assertTrackedState(fileArr, true);
-
-		UntrackOperation utop = new UntrackOperation(Arrays.asList(fileArr));
-
-		utop.execute(new NullProgressMonitor());
-
-		assertTrackedState(fileArr, false);
-	}
-
-	@SuppressWarnings("boxing")
-	private void assertTrackedState(IFile[] fileArr, boolean expectedState)
-			throws IOException {
-		DirCache cache = repository1.getRepository().readDirCache();
-		for (IFile file : fileArr) {
-			RepositoryMapping rm = RepositoryMapping.getMapping(file);
-			String fileDir = rm.getRepoRelativePath(file);
-			boolean tracked = cache.findEntry(fileDir) > -1;
-			assertEquals("Wrong tracking state", expectedState, tracked);
-		}
-	}
-
-	@Test
-	public void testTrackProject() throws Exception {
-
-		final ArrayList<IContainer> containers = new ArrayList<IContainer>();
-		containers.add(project);
-
-		final ArrayList<IFile> files = new ArrayList<IFile>();
-
-		project.accept(new IResourceVisitor() {
-
-			public boolean visit(IResource resource) throws CoreException {
-				if (resource instanceof IFile)
-					files.add((IFile) resource);
-				return true;
-			}
-		});
-
-		IFile[] fileArr = files.toArray(new IFile[files.size()]);
-
-		assertTrackedState(fileArr, false);
-
-		AddToIndexOperation trop = new AddToIndexOperation(containers);
-		trop.execute(new NullProgressMonitor());
-
-		assertTrackedState(fileArr, true);
-
-		UntrackOperation utrop = new UntrackOperation(containers);
-		utrop.execute(new NullProgressMonitor());
-
-		assertTrackedState(fileArr, false);
-	}
-
-}
diff --git a/org.eclipse.egit.core/.settings/.api_filters b/org.eclipse.egit.core/.settings/.api_filters
deleted file mode 100644
index 25de7db..0000000
--- a/org.eclipse.egit.core/.settings/.api_filters
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<component id="org.eclipse.egit.core" version="2">
-    <resource path="src/org/eclipse/egit/core/CoreText.java" type="org.eclipse.egit.core.CoreText">
-        <filter id="1143996420">
-            <message_arguments>
-                <message_argument value="MoveDeleteHook_unmergedFileError"/>
-            </message_arguments>
-        </filter>
-        <filter id="1143996420">
-            <message_arguments>
-                <message_argument value="MoveDeleteHook_unmergedFileInFolderError"/>
-            </message_arguments>
-        </filter>
-    </resource>
-    <resource path="src/org/eclipse/egit/core/op/IgnoreOperation.java" type="org.eclipse.egit.core.op.IgnoreOperation">
-        <filter comment="was removed in 2.2 and added back in 2.3, see bug 397544" id="1143996420">
-            <message_arguments>
-                <message_argument value="IgnoreOperation(IResource[])"/>
-            </message_arguments>
-        </filter>
-    </resource>
-</component>
diff --git a/org.eclipse.egit.core/META-INF/MANIFEST.MF b/org.eclipse.egit.core/META-INF/MANIFEST.MF
index d92315c..a1575a0 100644
--- a/org.eclipse.egit.core/META-INF/MANIFEST.MF
+++ b/org.eclipse.egit.core/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
 Bundle-Name: %plugin_name
 Bundle-SymbolicName: org.eclipse.egit.core;singleton:=true
 Bundle-Version: 3.0.0.qualifier
-Bundle-Activator: org.eclipse.egit.core.Activator
+Bundle-Activator: org.eclipse.egit.core.internal.Activator
 Bundle-Vendor: %provider_name
 Bundle-Localization: plugin
 Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.7.0,4.0.0)",
@@ -11,18 +11,17 @@
  org.eclipse.core.resources;bundle-version="[3.4.0,4.0.0)",
  org.eclipse.core.filesystem;bundle-version="[1.2.0,2.0.0)",
  org.eclipse.equinox.security;bundle-version="[1.0.0,2.0.0)"
-Export-Package: org.eclipse.egit.core;version="3.0.0",
- org.eclipse.egit.core.internal;version="3.0.0";x-friends:="org.eclipse.egit.ui,org.eclipse.egit.import",
+Export-Package: org.eclipse.egit.core.internal;version="3.0.0";x-friends:="org.eclipse.egit.ui,org.eclipse.egit.import",
  org.eclipse.egit.core.internal.indexdiff;version="3.0.0";x-friends:="org.eclipse.egit.ui",
  org.eclipse.egit.core.internal.job;version="3.0.0";x-friends:="org.eclipse.egit.ui",
+ org.eclipse.egit.core.internal.op;version="3.0.0",
+ org.eclipse.egit.core.internal.project;version="3.0.0",
+ org.eclipse.egit.core.internal.securestorage;version="3.0.0",
  org.eclipse.egit.core.internal.storage;version="3.0.0";x-friends:="org.eclipse.egit.ui,org.eclipse.egit.core.test",
+ org.eclipse.egit.core.internal.synchronize;version="3.0.0",
+ org.eclipse.egit.core.internal.synchronize.dto;version="3.0.0",
  org.eclipse.egit.core.internal.trace;version="3.0.0";x-internal:=true,
- org.eclipse.egit.core.internal.util;version="3.0.0";x-friends:="org.eclipse.egit.ui",
- org.eclipse.egit.core.op;version="3.0.0",
- org.eclipse.egit.core.project;version="3.0.0",
- org.eclipse.egit.core.securestorage;version="3.0.0",
- org.eclipse.egit.core.synchronize;version="3.0.0",
- org.eclipse.egit.core.synchronize.dto;version="3.0.0"
+ org.eclipse.egit.core.internal.util;version="3.0.0";x-friends:="org.eclipse.egit.ui"
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: J2SE-1.5
 Import-Package: org.eclipse.jgit.api;version="[3.0.0,3.1.0)",
diff --git a/org.eclipse.egit.core/plugin.xml b/org.eclipse.egit.core/plugin.xml
index 029a29f..860974e 100644
--- a/org.eclipse.egit.core/plugin.xml
+++ b/org.eclipse.egit.core/plugin.xml
@@ -2,12 +2,12 @@
 <?eclipse version="3.0"?>
 <plugin>
    <extension point="org.eclipse.core.runtime.preferences">
-      <initializer class="org.eclipse.egit.core.GitCorePreferenceInitializer"/>
+      <initializer class="org.eclipse.egit.core.internal.GitCorePreferenceInitializer"/>
    </extension>
 
   <extension point="org.eclipse.team.core.repository">
 	<repository
-       class="org.eclipse.egit.core.GitProvider"
+       class="org.eclipse.egit.core.internal.GitProvider"
        id="org.eclipse.egit.core.GitProvider"
        typeClass="org.eclipse.egit.core.internal.GitRepositoryProviderType">
 	</repository>
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/Activator.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/Activator.java
deleted file mode 100644
index 3aa7854..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/Activator.java
+++ /dev/null
@@ -1,383 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * Copyright (C) 2011, 2013 Matthias Sohn <matthias.sohn@sap.com>
- * Copyright (C) 2013, Robin Stocker <robin@nibor.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core;
-
-import java.io.File;
-import java.io.IOException;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Dictionary;
-import java.util.Hashtable;
-import java.util.List;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IResourceChangeEvent;
-import org.eclipse.core.resources.IResourceChangeListener;
-import org.eclipse.core.resources.IResourceDelta;
-import org.eclipse.core.resources.IResourceDeltaVisitor;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.Plugin;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.preferences.DefaultScope;
-import org.eclipse.core.runtime.preferences.IEclipsePreferences;
-import org.eclipse.core.runtime.preferences.InstanceScope;
-import org.eclipse.egit.core.internal.indexdiff.IndexDiffCache;
-import org.eclipse.egit.core.internal.job.JobUtil;
-import org.eclipse.egit.core.internal.trace.GitTraceLocation;
-import org.eclipse.egit.core.op.ConnectProviderOperation;
-import org.eclipse.egit.core.op.IgnoreOperation;
-import org.eclipse.egit.core.project.GitProjectData;
-import org.eclipse.egit.core.project.RepositoryFinder;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.core.securestorage.EGitSecureStore;
-import org.eclipse.equinox.security.storage.SecurePreferencesFactory;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.util.FS;
-import org.eclipse.osgi.service.debug.DebugOptions;
-import org.eclipse.osgi.service.debug.DebugOptionsListener;
-import org.eclipse.team.core.RepositoryProvider;
-import org.osgi.framework.BundleContext;
-
-/**
- * The plugin class for the org.eclipse.egit.core plugin. This
- * is a singleton class.
- */
-public class Activator extends Plugin implements DebugOptionsListener {
-	private static Activator plugin;
-	private static String pluginId;
-	private RepositoryCache repositoryCache;
-	private IndexDiffCache indexDiffCache;
-	private RepositoryUtil repositoryUtil;
-	private EGitSecureStore secureStore;
-	private AutoShareProjects shareGitProjectsJob;
-	private IResourceChangeListener preDeleteProjectListener;
-	private IgnoreDerivedResources ignoreDerivedResourcesListener;
-
-	/**
-	 * @return the singleton {@link Activator}
-	 */
-	public static Activator getDefault() {
-		return plugin;
-	}
-
-	/**
-	 * @return the name of this plugin
-	 */
-	public static String getPluginId() {
-		return pluginId;
-	}
-
-	/**
-	 * Utility to create an error status for this plug-in.
-	 *
-	 * @param message User comprehensible message
-	 * @param thr cause
-	 * @return an initialized error status
-	 */
-	public static IStatus error(final String message, final Throwable thr) {
-		return new Status(IStatus.ERROR, getPluginId(), 0,	message, thr);
-	}
-
-	/**
-	 * Utility method to log errors in the Egit plugin.
-	 * @param message User comprehensible message
-	 * @param thr The exception through which we noticed the error
-	 */
-	public static void logError(final String message, final Throwable thr) {
-		getDefault().getLog().log(
-				new Status(IStatus.ERROR, getPluginId(), 0, message, thr));
-	}
-
-	/**
-	 * Construct the {@link Activator} singleton instance
-	 */
-	public Activator() {
-		Activator.setActivator(this);
-	}
-
-	private static void setActivator(Activator a) {
-		plugin = a;
-	}
-
-	public void start(final BundleContext context) throws Exception {
-
-		super.start(context);
-
-		pluginId = context.getBundle().getSymbolicName();
-
-		// we want to be notified about debug options changes
-		Dictionary<String, String> props = new Hashtable<String, String>(4);
-		props.put(DebugOptions.LISTENER_SYMBOLICNAME, pluginId);
-		context.registerService(DebugOptionsListener.class.getName(), this,
-				props);
-
-		repositoryCache = new RepositoryCache();
-		indexDiffCache = new IndexDiffCache();
-		try {
-			GitProjectData.reconfigureWindowCache();
-		} catch (RuntimeException e) {
-			logError(CoreText.Activator_ReconfigureWindowCacheError, e);
-		}
-		GitProjectData.attachToWorkspace(true);
-
-		IEclipsePreferences node = InstanceScope.INSTANCE.getNode(Activator.getPluginId());
-		String gitPrefix = node.get(GitCorePreferences.core_gitPrefix, null);
-		if (gitPrefix != null)
-			FS.DETECTED.setGitPrefix(new File(gitPrefix));
-
-		repositoryUtil = new RepositoryUtil();
-
-		secureStore = new EGitSecureStore(SecurePreferencesFactory.getDefault());
-
-		registerAutoShareProjects();
-		registerAutoIgnoreDerivedResources();
-		registerPreDeleteResourceChangeListener();
-	}
-
-	private void registerPreDeleteResourceChangeListener() {
-		if (preDeleteProjectListener == null) {
-			preDeleteProjectListener = new IResourceChangeListener() {
-
-				public void resourceChanged(IResourceChangeEvent event) {
-					IResource resource = event.getResource();
-					if (resource instanceof IProject) {
-						IProject project = (IProject) resource;
-						if (RepositoryProvider.getProvider(project) instanceof GitProvider) {
-							IResource dotGit = project.findMember(Constants.DOT_GIT);
-							if (dotGit != null && dotGit.getType() == IResource.FOLDER)
-								GitProjectData.reconfigureWindowCache();
-						}
-					}
-				}
-			};
-			ResourcesPlugin.getWorkspace().addResourceChangeListener(preDeleteProjectListener, IResourceChangeEvent.PRE_DELETE);
-		}
-	}
-
-	public void optionsChanged(DebugOptions options) {
-		// initialize the trace stuff
-		GitTraceLocation.initializeFromOptions(options, isDebugging());
-	}
-
-	/**
-	 *  @return cache for Repository objects
-	 */
-	public RepositoryCache getRepositoryCache() {
-		return repositoryCache;
-	}
-
-	/**
-	 *  @return cache for index diffs
-	 */
-	public IndexDiffCache getIndexDiffCache() {
-		return indexDiffCache;
-	}
-
-	/**
-	 * @return the {@link RepositoryUtil} instance
-	 */
-	public RepositoryUtil getRepositoryUtil() {
-		return repositoryUtil;
-	}
-
-	/**
-	 * @return the secure store
-	 */
-	public EGitSecureStore getSecureStore() {
-		return secureStore;
-	}
-
-	public void stop(final BundleContext context) throws Exception {
-		GitProjectData.detachFromWorkspace();
-		repositoryCache = null;
-		indexDiffCache.dispose();
-		indexDiffCache = null;
-		repositoryUtil.dispose();
-		repositoryUtil = null;
-		secureStore = null;
-		super.stop(context);
-		plugin = null;
-		if (preDeleteProjectListener != null) {
-			ResourcesPlugin.getWorkspace().removeResourceChangeListener(preDeleteProjectListener);
-			preDeleteProjectListener = null;
-		}
-		if (ignoreDerivedResourcesListener != null) {
-			ResourcesPlugin.getWorkspace().removeResourceChangeListener(
-					ignoreDerivedResourcesListener);
-			ignoreDerivedResourcesListener = null;
-		}
-		if (shareGitProjectsJob != null) {
-			ResourcesPlugin.getWorkspace().removeResourceChangeListener(
-					shareGitProjectsJob);
-			shareGitProjectsJob = null;
-		}
-	}
-
-	private void registerAutoShareProjects() {
-		shareGitProjectsJob = new AutoShareProjects();
-		ResourcesPlugin.getWorkspace().addResourceChangeListener(
-				shareGitProjectsJob, IResourceChangeEvent.POST_CHANGE);
-	}
-
-	private static class AutoShareProjects implements
-			IResourceChangeListener {
-
-		private static int INTERESTING_CHANGES = IResourceDelta.ADDED
-				| IResourceDelta.OPEN;
-
-		public AutoShareProjects() {
-			// empty
-		}
-
-		private boolean doAutoShare() {
-			IEclipsePreferences d = DefaultScope.INSTANCE.getNode(Activator
-					.getPluginId());
-			IEclipsePreferences p = InstanceScope.INSTANCE.getNode(Activator
-					.getPluginId());
-			return p.getBoolean(GitCorePreferences.core_autoShareProjects, d
-					.getBoolean(GitCorePreferences.core_autoShareProjects,
-							true));
-		}
-
-		public void resourceChanged(IResourceChangeEvent event) {
-			try {
-				event.getDelta().accept(new IResourceDeltaVisitor() {
-
-					public boolean visit(IResourceDelta delta)
-							throws CoreException {
-						if (!doAutoShare())
-							return false;
-						if (delta.getKind() == IResourceDelta.CHANGED
-								&& (delta.getFlags() & INTERESTING_CHANGES) == 0)
-							return true;
-						final IResource resource = delta.getResource();
-						if (!resource.exists() || !resource.isAccessible() ||
-								resource.isLinked(IResource.CHECK_ANCESTORS))
-							return false;
-						if (resource.getType() != IResource.PROJECT)
-							return true;
-						if (RepositoryMapping.getMapping(resource) != null)
-							return false;
-						final IProject project = (IProject) resource;
-						RepositoryProvider provider = RepositoryProvider
-								.getProvider(project);
-						// respect if project is already shared with another
-						// team provider
-						if (provider != null)
-							return false;
-						RepositoryFinder f = new RepositoryFinder(project);
-						Collection<RepositoryMapping> mappings = f.find(new NullProgressMonitor());
-						try {
-							if (mappings.size() == 1) {
-								// connect
-								RepositoryMapping m = mappings.iterator()
-										.next();
-								final File repositoryDir = m
-										.getGitDirAbsolutePath().toFile();
-								final ConnectProviderOperation op = new ConnectProviderOperation(
-										project, repositoryDir);
-								JobUtil.scheduleUserJob(op,
-										CoreText.Activator_AutoShareJobName,
-										JobFamilies.AUTO_SHARE);
-								Activator.getDefault().getRepositoryUtil()
-										.addConfiguredRepository(repositoryDir);
-							}
-						} catch (IllegalArgumentException e) {
-							logError(CoreText.Activator_AutoSharingFailed, e);
-						}
-						return false;
-					}
-				});
-			} catch (CoreException e) {
-				Activator.logError(e.getMessage(), e);
-				return;
-			}
-		}
-	}
-
-	private void registerAutoIgnoreDerivedResources() {
-		ignoreDerivedResourcesListener = new IgnoreDerivedResources();
-		ResourcesPlugin.getWorkspace().addResourceChangeListener(
-				ignoreDerivedResourcesListener,
-				IResourceChangeEvent.POST_CHANGE);
-	}
-
-	private static class IgnoreDerivedResources implements
-			IResourceChangeListener {
-
-		protected boolean autoIgnoreDerived() {
-			IEclipsePreferences d = DefaultScope.INSTANCE.getNode(Activator
-					.getPluginId());
-			IEclipsePreferences p = InstanceScope.INSTANCE.getNode(Activator
-					.getPluginId());
-			return p.getBoolean(
-					GitCorePreferences.core_autoIgnoreDerivedResources,
-					d.getBoolean(
-							GitCorePreferences.core_autoIgnoreDerivedResources,
-							true));
-		}
-
-		public void resourceChanged(IResourceChangeEvent event) {
-			try {
-				IResourceDelta d = event.getDelta();
-				if (d == null || !autoIgnoreDerived())
-					return;
-
-				final List<IPath> toBeIgnored = new ArrayList<IPath>();
-
-				d.accept(new IResourceDeltaVisitor() {
-
-					public boolean visit(IResourceDelta delta)
-							throws CoreException {
-						if ((delta.getKind() & (IResourceDelta.ADDED | IResourceDelta.CHANGED)) == 0)
-							return false;
-						int flags = delta.getFlags();
-						if ((flags != 0)
-								&& ((flags & IResourceDelta.DERIVED_CHANGED) == 0))
-							return false;
-
-						final IResource r = delta.getResource();
-						if (r.isTeamPrivateMember())
-							return false;
-
-						if (r.isDerived()) {
-							try {
-								if (!RepositoryUtil.isIgnored(r.getLocation()))
-									toBeIgnored.add(r.getLocation());
-							} catch (IOException e) {
-								logError(
-										MessageFormat.format(
-												CoreText.Activator_ignoreResourceFailed,
-												r.getFullPath()), e);
-							}
-							return false;
-						}
-						return true;
-					}
-				});
-				if (toBeIgnored.size() > 0)
-					JobUtil.scheduleUserJob(new IgnoreOperation(toBeIgnored),
-							CoreText.Activator_autoIgnoreDerivedResources,
-							JobFamilies.AUTO_IGNORE);
-			} catch (CoreException e) {
-				Activator.logError(e.getMessage(), e);
-				return;
-			}
-		}
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/AdaptableFileTreeIterator.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/AdaptableFileTreeIterator.java
deleted file mode 100644
index 9cb8ed4..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/AdaptableFileTreeIterator.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2009, Tor Arne Vestbø <torarnv@gmail.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-
-package org.eclipse.egit.core;
-
-import java.io.File;
-import java.io.IOException;
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IWorkspaceRoot;
-import org.eclipse.jgit.errors.IncorrectObjectTypeException;
-import org.eclipse.jgit.lib.ObjectReader;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.treewalk.AbstractTreeIterator;
-import org.eclipse.jgit.treewalk.FileTreeIterator;
-import org.eclipse.jgit.treewalk.WorkingTreeIterator;
-import org.eclipse.jgit.util.FS;
-
-/**
- * Java IO file tree iterator that can adapt to a {@link ContainerTreeIterator}
- * <p>
- * The iterator automatically adapts to a {@link ContainerTreeIterator} when
- * recursing into directories that are accessible from the given workspace root.
- *
- * @see org.eclipse.jgit.treewalk.FileTreeIterator
- * @see org.eclipse.egit.core.ContainerTreeIterator
- */
-public class AdaptableFileTreeIterator extends FileTreeIterator {
-
-	IWorkspaceRoot root;
-
-	/**
-	 * Create a new iterator to traverse the work tree of the given repository
-	 * <p>
-	 * The iterator will automatically adapt to a {@link ContainerTreeIterator}
-	 * when encountering directories what can be mapped into the given workspace
-	 * root.
-	 *
-	 * @param repository
-	 *            the repository this iterator should traverse the working tree
-	 *            of
-	 * @param workspaceRoot
-	 *            the workspace root to check resource mapping against.
-	 */
-	public AdaptableFileTreeIterator(final Repository repository,
-			final IWorkspaceRoot workspaceRoot) {
-		super(repository);
-		root = workspaceRoot;
-	}
-
-	/**
-	 * Create a new iterator to traverse a subdirectory.
-	 * <p>
-	 * The iterator will automatically adapt to a {@link ContainerTreeIterator}
-	 * when encountering directories what can be mapped into the given workspace
-	 * root.
-	 *
-	 * @param path
-	 *            the subdirectory. This should be a directory contained within
-	 *            the parent directory.
-	 * @param parent
-	 *            the parent iterator we were created from.
-	 * @param workspaceRoot
-	 *            the workspace root to check resource mapping against.
-	 */
-	protected AdaptableFileTreeIterator(final WorkingTreeIterator parent,
-			File path, final IWorkspaceRoot workspaceRoot) {
-		super(parent, path, FS.DETECTED);
-		root = workspaceRoot;
-	}
-
-	@Override
-	public AbstractTreeIterator createSubtreeIterator(ObjectReader repo)
-			throws IncorrectObjectTypeException, IOException {
-		final File currentFile = ((FileEntry) current()).getFile();
-		IContainer container = IteratorService.findContainer(root, currentFile);
-		if (container != null)
-			return new ContainerTreeIterator(this, container);
-		return new AdaptableFileTreeIterator(this, currentFile, root);
-	}
-
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/AdapterUtils.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/AdapterUtils.java
deleted file mode 100644
index e154b29..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/AdapterUtils.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/******************************************************************************
- *  Copyright (c) 2011 GitHub Inc.
- *  All rights reserved. This program and the accompanying materials
- *  are made available under the terms of the Eclipse Public License v1.0
- *  which accompanies this distribution, and is available at
- *  http://www.eclipse.org/legal/epl-v10.html
- *
- *  Contributors:
- *    Kevin Sawicki (GitHub Inc.) - initial API and implementation
- *****************************************************************************/
-package org.eclipse.egit.core;
-
-import org.eclipse.core.runtime.IAdaptable;
-
-/**
- * Utilities for working with objects that implement {@link IAdaptable}
- */
-public class AdapterUtils {
-
-	private AdapterUtils() {
-		// Cannot be instantiated
-	}
-
-	/**
-	 * Adapt object to given target class type
-	 *
-	 * @param object
-	 * @param target
-	 * @param <V> type of target
-	 * @return adapted
-	 */
-	@SuppressWarnings("unchecked")
-	public static <V> V adapt(Object object, Class<V> target) {
-		if (object == null)
-			return null;
-		if (target.isInstance(object))
-			return (V) object;
-		if (object instanceof IAdaptable)
-			return (V) ((IAdaptable) object).getAdapter(target);
-		return null;
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/ContainerTreeIterator.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/ContainerTreeIterator.java
deleted file mode 100644
index 5ae3249..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/ContainerTreeIterator.java
+++ /dev/null
@@ -1,375 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2008, 2012 Google Inc. and others.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-
-package org.eclipse.egit.core;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IResourceFilterDescription;
-import org.eclipse.core.resources.IWorkspaceRoot;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.jgit.errors.IncorrectObjectTypeException;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.lib.FileMode;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.ObjectReader;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.treewalk.AbstractTreeIterator;
-import org.eclipse.jgit.treewalk.FileTreeIterator.FileEntry;
-import org.eclipse.jgit.treewalk.WorkingTreeIterator;
-import org.eclipse.jgit.treewalk.WorkingTreeOptions;
-import org.eclipse.jgit.util.FS;
-
-/**
- * Adapts an Eclipse {@link IContainer} for use in a <code>TreeWalk</code>.
- * <p>
- * This iterator converts an Eclipse IContainer object into something that a
- * TreeWalk instance can iterate over in parallel with any other Git tree data
- * structure, such as another working directory tree from outside of the
- * workspace or a stored tree from a Repository object database.
- * <p>
- * Modification times provided by this iterator are obtained from the cache
- * Eclipse uses to track external resource modification. This can be faster, but
- * requires the user refresh their workspace when external modifications take
- * place. This is not really a concern as it is common practice to need to do a
- * workspace refresh after externally modifying a file.
- *
- * @see org.eclipse.jgit.treewalk.TreeWalk
- */
-public class ContainerTreeIterator extends WorkingTreeIterator {
-
-	private static String computePrefix(final IContainer base) {
-		final RepositoryMapping rm = RepositoryMapping.getMapping(base);
-		if (rm == null)
-			throw new IllegalArgumentException(
-					"Not in a Git project: " + base);  //$NON-NLS-1$
-		return rm.getRepoRelativePath(base);
-	}
-
-	private final IContainer node;
-
-	/**
-	 * Construct a new iterator from a container in the workspace.
-	 * <p>
-	 * The iterator will support traversal over the named container, but only if
-	 * it is contained within a project which has the Git repository provider
-	 * connected and this resource is mapped into a Git repository. During the
-	 * iteration the paths will be automatically generated to match the proper
-	 * repository paths for this container's children.
-	 *
-	 * @param repository
-	 *            repository the given base is mapped to
-	 * @param base
-	 *            the part of the workspace the iterator will walk over.
-	 */
-	public ContainerTreeIterator(final Repository repository, final IContainer base) {
-		super(computePrefix(base), repository.getConfig().get(WorkingTreeOptions.KEY));
-		node = base;
-		init(entries(false));
-		initRootIterator(repository);
-	}
-
-	/**
-	 * Construct a new iterator from the workspace root.
-	 * <p>
-	 * The iterator will support traversal over workspace projects that have
-	 * a Git repository provider connected and is mapped into a Git repository.
-	 * During the iteration the paths will be automatically generated to match
-	 * the proper repository paths for this container's children.
-	 *
-	 * @param repository
-	 *            repository the given base is mapped to
-	 * @param root
-	 *            the workspace root to walk over.
-	 */
-	public ContainerTreeIterator(final Repository repository, final IWorkspaceRoot root) {
-		super("", repository.getConfig().get(WorkingTreeOptions.KEY));  //$NON-NLS-1$
-		node = root;
-		init(entries(false));
-		initRootIterator(repository);
-	}
-
-	/**
-	 * Construct a new iterator from a container in the workspace, with a given
-	 * parent iterator.
-	 * <p>
-	 * The iterator will support traversal over the named container, but only if
-	 * it is contained within a project which has the Git repository provider
-	 * connected and this resource is mapped into a Git repository. During the
-	 * iteration the paths will be automatically generated to match the proper
-	 * repository paths for this container's children.
-	 *
-	 * @param p
-	 *            the parent iterator we were created from.
-	 * @param base
-	 *            the part of the workspace the iterator will walk over.
-	 */
-	public ContainerTreeIterator(final WorkingTreeIterator p,
-			final IContainer base) {
-		this(p, base, false);
-	}
-
-	private ContainerTreeIterator(final WorkingTreeIterator p,
-			final IContainer base, final boolean hasInheritedResourceFilters) {
-		super(p);
-		node = base;
-		init(entries(hasInheritedResourceFilters));
-	}
-
-	@Override
-	public AbstractTreeIterator createSubtreeIterator(ObjectReader reader)
-			throws IncorrectObjectTypeException, IOException {
-		if (FileMode.TREE.equals(mode)) {
-			if (current() instanceof ResourceEntry) {
-				ResourceEntry resourceEntry = (ResourceEntry) current();
-				return new ContainerTreeIterator(this,
-						(IContainer) resourceEntry.rsrc,
-						resourceEntry.hasInheritedResourceFilters);
-			} else if (current() instanceof FileEntry) {
-				FileEntry fileEntry = (FileEntry) current();
-				IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
-				return new AdaptableFileTreeIterator(this, fileEntry.getFile(), root);
-			} else {
-				throw new IllegalStateException("Unknown entry type: " + current()); //$NON-NLS-1$
-			}
-		} else
-			throw new IncorrectObjectTypeException(ObjectId.zeroId(),
-					Constants.TYPE_TREE);
-	}
-
-	/**
-	 * Get the ResourceEntry for the current entry.
-	 *
-	 * @return the current entry
-	 */
-	public ResourceEntry getResourceEntry() {
-		return (ResourceEntry) current();
-	}
-
-	private Entry[] entries(final boolean hasInheritedResourceFilters) {
-		final IResource[] resources;
-		try {
-			resources = node.members(IContainer.INCLUDE_HIDDEN);
-		} catch (CoreException err) {
-			return EOF;
-		}
-
-		List<Entry> entries = new ArrayList<Entry>(resources.length);
-
-		boolean inheritableResourceFilter = addFilteredEntries(
-				hasInheritedResourceFilters, resources, entries);
-
-		for (IResource resource : resources)
-			if (!resource.isLinked())
-				entries.add(new ResourceEntry(resource, inheritableResourceFilter));
-
-		return entries.toArray(new Entry[entries.size()]);
-	}
-
-	/**
-	 * Add entries for filtered resources.
-	 *
-	 * @param hasInheritedResourceFilters
-	 *            true if resource filters of parents could be active, false
-	 *            otherwise
-	 * @param memberResources
-	 *            the resources returned from members() that do not have to be
-	 *            added as entries again
-	 * @param entries
-	 *            where entries should be added to
-	 * @return true if we now have resource filters that are inherited, false if
-	 *         there are no resource filters which are inherited.
-	 */
-	private boolean addFilteredEntries(
-			final boolean hasInheritedResourceFilters,
-			final IResource[] memberResources, final List<Entry> entries) {
-		// Inheritable resource filters must be propagated.
-		boolean inheritableResourceFilter = hasInheritedResourceFilters;
-		IResourceFilterDescription[] filters;
-		try {
-			filters = node.getFilters();
-		} catch (CoreException e) {
-			// Should not happen, but assume we have no filters then.
-			filters = new IResourceFilterDescription[] {};
-		}
-
-		if (filters.length != 0 || hasInheritedResourceFilters) {
-			if (!inheritableResourceFilter) {
-				for (IResourceFilterDescription filter : filters) {
-					boolean inheritable = (filter.getType() & IResourceFilterDescription.INHERITABLE) != 0;
-					if (inheritable)
-						inheritableResourceFilter = true;
-				}
-			}
-
-			Set<File> resourceEntries = new HashSet<File>();
-			for (IResource resource : memberResources)
-				// Make sure linked resources are ignored here.
-				// This is particularly important in the case of a linked
-				// resource which targets a normally filtered/hidden file
-				// within the same location. In such case, ignoring it here
-				// ensures the actual target gets included in the code below.
-				if (!resource.isLinked()) {
-					IPath location = resource.getLocation();
-					if (location != null)
-						resourceEntries.add(location.toFile());
-				}
-
-			IPath containerLocation = node.getLocation();
-			if (containerLocation != null) {
-				File folder = containerLocation.toFile();
-				File[] children = folder.listFiles();
-				for (File child : children) {
-					if (resourceEntries.contains(child))
-						continue; // ok if linked resources are ignored earlier on
-					IPath childLocation = new Path(child.getAbsolutePath());
-					IWorkspaceRoot root = node.getWorkspace().getRoot();
-					IContainer container = root.getContainerForLocation(childLocation);
-					// Check if the container is accessible in the workspace.
-					// This may seem strange, as it was not returned from
-					// members() above, but it's the case for nested projects
-					// that are filtered directly.
-					if (container != null && container.isAccessible())
-						// Resource filters does not cross the non-member line
-						// -> stop inheriting resource filter here (false)
-						entries.add(new ResourceEntry(container, false));
-					else
-						entries.add(new FileEntry(child, FS.DETECTED));
-				}
-			}
-		}
-		return inheritableResourceFilter;
-	}
-
-	/**
-	 * Wrapper for a resource in the Eclipse workspace
-	 */
-	static public class ResourceEntry extends Entry {
-		final IResource rsrc;
-		final boolean hasInheritedResourceFilters;
-
-		private final FileMode mode;
-
-		private long length = -1;
-
-		ResourceEntry(final IResource f, final boolean hasInheritedResourceFilters) {
-			rsrc = f;
-			this.hasInheritedResourceFilters = hasInheritedResourceFilters;
-
-			switch (f.getType()) {
-			case IResource.FILE:
-				File file = asFile();
-				if (FS.DETECTED.supportsExecute() && file != null
-						&& FS.DETECTED.canExecute(file))
-					mode = FileMode.EXECUTABLE_FILE;
-				else
-					mode = FileMode.REGULAR_FILE;
-				break;
-			case IResource.PROJECT:
-			case IResource.FOLDER: {
-				final IContainer c = (IContainer) f;
-				if (c.findMember(Constants.DOT_GIT) != null)
-					mode = FileMode.GITLINK;
-				else
-					mode = FileMode.TREE;
-				break;
-			}
-			default:
-				mode = FileMode.MISSING;
-				break;
-			}
-		}
-
-		@Override
-		public FileMode getMode() {
-			return mode;
-		}
-
-		@Override
-		public String getName() {
-			if (rsrc.getType() == IResource.PROJECT)
-				return rsrc.getLocation().lastSegment();
-			else
-				return rsrc.getName();
-		}
-
-		@Override
-		public long getLength() {
-			if (length < 0)
-				if (rsrc instanceof IFile) {
-					File file = asFile();
-					if (file != null)
-						length = file.length();
-					else
-						length = 0;
-				} else
-					length = 0;
-			return length;
-		}
-
-		@Override
-		public long getLastModified() {
-			return rsrc.getLocalTimeStamp();
-		}
-
-		@Override
-		public InputStream openInputStream() throws IOException {
-			if (rsrc.getType() == IResource.FILE)
-				try {
-					return ((IFile) rsrc).getContents(true);
-				} catch (CoreException err) {
-					final IOException ioe = new IOException(err.getMessage());
-					ioe.initCause(err);
-					throw ioe;
-				}
-			throw new IOException("Not a regular file: " + rsrc);  //$NON-NLS-1$
-		}
-
-		/**
-		 * Get the underlying resource of this entry.
-		 *
-		 * @return the underlying resource
-		 */
-		public IResource getResource() {
-			return rsrc;
-		}
-
-		/**
-		 * @return file of the resource or null
-		 */
-		private File asFile() {
-			return ContainerTreeIterator.asFile(rsrc);
-		}
-	}
-
-	private static File asFile(IResource resource) {
-		final IPath location = resource.getLocation();
-		return location != null ? location.toFile() : null;
-	}
-
-	protected byte[] idSubmodule(Entry e) {
-		File nodeFile = asFile(node);
-		if (nodeFile != null)
-			return idSubmodule(nodeFile, e);
-		return super.idSubmodule(e);
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/CoreText.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/CoreText.java
deleted file mode 100644
index 9a7675d..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/CoreText.java
+++ /dev/null
@@ -1,435 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * Copyright (C) 2012, Robin Stocker <robin@nibor.org>
- * Copyright (C) 2012, Markus Duft <markus.duft@salomon.at>
- * Copyright (C) 2013, Matthias Sohn <matthias.sohn@sap.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core;
-
-import org.eclipse.osgi.util.NLS;
-
-/**
- * Possibly Translated strings for the Egit plugin.
- */
-public class CoreText extends NLS {
-
-	/**
-	 * Do not in-line this into the static initializer as the
-	 * "Find Broken Externalized Strings" tool will not be
-	 * able to find the corresponding bundle file.
-	 */
-	private static final String BUNDLE_NAME = "org.eclipse.egit.core.coretext"; //$NON-NLS-1$
-
-	/** */
-	public static String Activator_autoIgnoreDerivedResources;
-
-	/** */
-	public static String Activator_AutoShareJobName;
-
-	/** */
-	public static String Activator_AutoSharingFailed;
-
-	/** */
-	public static String Activator_ignoreResourceFailed;
-
-	/** */
-	public static String Activator_ReconfigureWindowCacheError;
-
-	/** */
-	public static String AssumeUnchangedOperation_adding;
-
-	/** */
-	public static String AssumeUnchangedOperation_writingIndex;
-
-	/** */
-	public static String CherryPickOperation_cherryPicking;
-
-	/** */
-	public static String CommitFileRevision_errorLookingUpPath;
-
-	/** */
-	public static String CommitFileRevision_pathNotIn;
-
-	/** */
-	public static String CommitOperation_errorCommittingChanges;
-
-	/** */
-	public static String CommitOperation_errorPreparingTrees;
-
-	/** */
-	public static String CommitOperation_errorWritingTrees;
-
-	/** */
-	public static String CommitOperation_failedToUpdate;
-
-	/** */
-	public static String CommitOperation_PerformingCommit;
-
-	/** */
-	public static String CommitOperation_couldNotFindRepositoryMapping;
-
-	/** */
-	public static String CommitOperation_errorParsingPersonIdent;
-
-	/** */
-	public static String ConfigureFetchAfterCloneTask_couldNotFetch;
-
-	/** */
-	public static String ConnectProviderOperation_connecting;
-
-	/** */
-	public static String ConnectProviderOperation_ConnectingProject;
-
-	/** */
-	public static String DeleteBranchOperation_TaskName;
-
-	/** */
-	public static String DeleteTagOperation_exceptionMessage;
-
-	/** */
-	public static String DiffHeaderFormat_Email;
-
-	/** */
-	public static String DiffHeaderFormat_None;
-
-	/** */
-	public static String DiffHeaderFormat_Oneline;
-
-	/** */
-	public static String DiffHeaderFormat_Workspace;
-
-	/** */
-	public static String DiscardChangesOperation_discardFailed;
-
-	/** */
-	public static String DiscardChangesOperation_discardFailedSeeLog;
-
-	/** */
-	public static String DiscardChangesOperation_discardingChanges;
-
-	/** */
-	public static String DiscardChangesOperation_refreshFailed;
-
-	/** */
-	public static String DeleteResourcesOperation_deletingResources;
-
-	/** */
-	public static String DeleteResourcesOperation_deleteFailed;
-
-	/** */
-	public static String DeleteResourcesOperation_deleteFailedSeeLog;
-
-	/** */
-	public static String DisconnectProviderOperation_disconnecting;
-
-	/** */
-	public static String BlobStorage_blobNotFound;
-
-	/** */
-	public static String BlobStorage_errorReadingBlob;
-
-	/** */
-	public static String UntrackOperation_adding;
-
-	/** */
-	public static String UntrackOperation_failed;
-
-	/** */
-	public static String UntrackOperation_writingIndex;
-
-	/** */
-	public static String GitFileHistory_errorParsingHistory;
-
-	/** */
-	public static String GitFileHistory_gitNotAttached;
-
-	/** */
-	public static String GitFileHistory_invalidHeadRevision;
-
-	/** */
-	public static String GitFileHistory_noHeadRevisionAvailable;
-
-	/** */
-	public static String GitProjectData_mappedResourceGone;
-
-	/** */
-	public static String GitProjectData_failedFindingRepoMapping;
-
-	/** */
-	public static String GitProjectData_failedToCacheRepoMapping;
-
-	/** */
-	public static String GitProjectData_FailedToMarkTeamPrivate;
-
-	/** */
-	public static String GitProjectData_missing;
-
-	/** */
-	public static String GitProjectData_saveFailed;
-
-	/** */
-	public static String RepositoryFinder_finding;
-
-	/** */
-	public static String RepositoryUtil_noHead;
-
-	/** */
-	public static String RemoteRefUpdateCantBeReused;
-
-	/** */
-	public static String RenameBranchOperation_TaskName;
-
-	/** */
-	public static String ResetOperation_cantUpdate;
-
-	/** */
-	public static String ResetOperation_lookingUpCommit;
-
-	/** */
-	public static String ResetOperation_lookingUpRef;
-
-	/** */
-	public static String ResetOperation_mappingTreeForCommit;
-
-	/** */
-	public static String ResetOperation_performingReset;
-
-	/** */
-	public static String ResetOperation_readingIndex;
-
-	/** */
-	public static String ResetOperation_resetMergeFailed;
-
-	/** */
-	public static String ResetOperation_resetCherryPickFailed;
-
-	/** */
-	public static String ResetOperation_updatingFailed;
-
-	/** */
-	public static String MergeOperation_CheckoutConflict;
-
-	/** */
-	public static String MergeOperation_InternalError;
-
-	/** */
-	public static String MergeOperation_MergeFailedNoHead;
-
-	/** */
-	public static String MergeOperation_MergeFailedRefUpdate;
-
-	/** */
-	public static String MergeOperation_ProgressMerge;
-
-	/** */
-	public static String MoveDeleteHook_cannotModifyFolder;
-
-	/** */
-	public static String MoveDeleteHook_operationError;
-
-	/** */
-	public static String MoveDeleteHook_unmergedFileError;
-
-	/** */
-	public static String MoveDeleteHook_unmergedFileInFolderError;
-
-	/** */
-	public static String Error_CanonicalFile;
-
-	/** */
-	public static String CloneOperation_checkingOutFiles;
-
-	/** */
-	public static String CloneOperation_failed_cleanup;
-
-	/** */
-	public static String CloneOperation_initializingRepository;
-
-	/** */
-	public static String CloneOperation_title;
-
-	/** */
-	public static String CloneOperation_writingIndex;
-
-	/** */
-	public static String CreateLocalBranchOperation_CreatingBranchMessage;
-
-	/** */
-	public static String CreatePatchOperation_repoRequired;
-
-	/** */
-	public static String CreatePatchOperation_cannotCreatePatchForMergeCommit;
-
-	/** */
-	public static String CreatePatchOperation_cannotCreatePatchForFirstCommit;
-
-	/** */
-	public static String CreatePatchOperation_couldNotFindProject;
-
-	/** */
-	public static String CreatePatchOperation_patchFileCouldNotBeWritten;
-
-	/** */
-	public static String IndexDiffCacheEntry_errorCalculatingIndexDelta;
-
-	/** */
-	public static String IndexDiffCacheEntry_refreshingProjects;
-
-	/** */
-	public static String IndexDiffCacheEntry_reindexing;
-
-	/** */
-	public static String IndexFileRevision_errorLookingUpPath;
-
-	/** */
-	public static String IndexFileRevision_indexEntryNotFound;
-
-	/** */
-	public static String ListRemoteOperation_title;
-
-	/** */
-	public static String ProjectUtil_refreshingProjects;
-
-	/** */
-	public static String ProjectUtil_refreshing;
-
-	/** */
-	public static String ProjectUtil_taskCheckingDirectory;
-
-	/** */
-	public static String PullOperation_DetachedHeadMessage;
-
-	/** */
-	public static String PullOperation_PullNotConfiguredMessage;
-
-	/** */
-	public static String PullOperation_TaskName;
-
-	/** */
-	public static String PushOperation_InternalExceptionOccurredMessage;
-
-	/** */
-	public static String PushOperation_ExceptionOccurredDuringPushOnUriMessage;
-
-	/** */
-	public static String PushOperation_resultCancelled;
-
-	/** */
-	public static String PushOperation_taskNameDryRun;
-
-	/** */
-	public static String PushOperation_taskNameNormalRun;
-
-	/** */
-	public static String AddToIndexOperation_failed;
-
-	/** */
-	public static String RemoveFromIndexOperation_removingFilesFromIndex;
-
-	/** */
-	public static String RemoveFromIndexOperation_failed;
-
-	/** */
-	public static String RevertCommitOperation_reverting;
-
-	/** */
-	public static String BranchOperation_closingMissingProject;
-
-	/** */
-	public static String BranchOperation_performingBranch;
-
-	/** */
-	public static String TagOperation_performingTagging;
-
-	/** */
-	public static String TagOperation_taggingFailure;
-
-	/** */
-	public static String TagOperation_objectIdNotFound;
-
-	/** */
-	public static String GitResourceVariantTree_couldNotFindResourceVariant;
-
-	/** */
-	public static String GitResourceVariantTree_couldNotFetchMembers;
-
-	/** */
-	public static String GitFolderResourceVariant_fetchingMembers;
-
-	/** */
-	public static String GitResourceVariantTree_fetchingVariant;
-
-	/** */
-	public static String GitBranchResourceVariantTreeSubscriber_gitRepository;
-
-	/** */
-	public static String OperationAlreadyExecuted;
-
-	/** */
-	public static String OperationNotYetExecuted;
-
-	/** */
-	public static String ProjectReference_InvalidTokensCount;
-
-	/** */
-	public static String GitProjectSetCapability_CloneToExistingDirectory;
-
-	/** */
-	public static String GitProjectSetCapability_ExportCouldNotGetBranch;
-
-	/** */
-	public static String GitProjectSetCapability_ExportNoRemote;
-
-	/** */
-	public static String IgnoreOperation_error;
-
-	/** */
-	public static String IgnoreOperation_parentOutsideRepo;
-
-	/** */
-	public static String IgnoreOperation_creatingFailed;
-
-	/** */
-	public static String IgnoreOperation_taskName;
-
-	/** */
-	public static String IgnoreOperation_updatingFailed;
-
-	/** */
-	public static String GitSubscriberMergeContext_FailedUpdateRevs;
-
-	/** */
-	public static String GitSubscriberMergeContext_FailedRefreshSyncView;
-
-	/** */
-	public static String GitProjectData_repositoryChangedJobName;
-
-	/** */
-	public static String GitProjectData_repositoryChangedTaskName;
-
-	/** */
-	public static String GitResourceVariantTreeSubscriber_fetchTaskName;
-
-	/** */
-	public static String GitSyncObjectCache_noData;
-
-	/** */
-	public static String GitRemoteFolder_fetchingMembers;
-
-	/** */
-	public static String GitURI_InvalidSCMURL;
-
-	/** */
-	public static String GitURI_InvalidURI;
-
-	static {
-		initializeMessages(BUNDLE_NAME,	CoreText.class);
-	}
-
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/EclipseGitProgressTransformer.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/EclipseGitProgressTransformer.java
deleted file mode 100644
index 67603dd..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/EclipseGitProgressTransformer.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.jgit.lib.ProgressMonitor;
-
-/** Create a new Git to Eclipse progress monitor. */
-public class EclipseGitProgressTransformer implements ProgressMonitor {
-	private static final String EMPTY_STRING = "";  //$NON-NLS-1$
-
-	private final IProgressMonitor root;
-
-	private IProgressMonitor task;
-
-	private String msg;
-
-	private int lastWorked;
-
-	private int totalWork;
-
-	/**
-	 * Create a new progress monitor.
-	 *
-	 * @param eclipseMonitor
-	 *            the Eclipse monitor we update.
-	 */
-	public EclipseGitProgressTransformer(final IProgressMonitor eclipseMonitor) {
-		root = eclipseMonitor;
-	}
-
-	public void start(final int totalTasks) {
-		root.beginTask(EMPTY_STRING, totalTasks * 1000);
-	}
-
-	public void beginTask(final String name, final int total) {
-		endTask();
-		msg = name;
-		lastWorked = 0;
-		totalWork = total;
-		task = new SubProgressMonitor(root, 1000);
-		if (totalWork == UNKNOWN)
-			task.beginTask(EMPTY_STRING, IProgressMonitor.UNKNOWN);
-		else
-			task.beginTask(EMPTY_STRING, totalWork);
-		task.subTask(msg);
-	}
-
-	public void update(final int work) {
-		if (task == null)
-			return;
-
-		final int cmp = lastWorked + work;
-		if (totalWork == UNKNOWN && cmp > 0) {
-			if (lastWorked != cmp)
-				task.subTask(msg + ", " + cmp); //$NON-NLS-1$
-		} else if (totalWork <= 0) {
-			// Do nothing to update the task.
-		} else if (cmp * 100 / totalWork != lastWorked * 100 / totalWork) {
-			final StringBuilder m = new StringBuilder();
-			m.append(msg);
-			m.append(": ");  //$NON-NLS-1$
-			while (m.length() < 25)
-				m.append(' ');
-
-			final String twstr = String.valueOf(totalWork);
-			String cmpstr = String.valueOf(cmp);
-			while (cmpstr.length() < twstr.length())
-				cmpstr = " " + cmpstr; //$NON-NLS-1$
-			final int pcnt = (cmp * 100 / totalWork);
-			if (pcnt < 100)
-				m.append(' ');
-			if (pcnt < 10)
-				m.append(' ');
-			m.append(pcnt);
-			m.append("% ("); //$NON-NLS-1$
-			m.append(cmpstr);
-			m.append("/"); //$NON-NLS-1$
-			m.append(twstr);
-			m.append(")"); //$NON-NLS-1$
-
-			task.subTask(m.toString());
-		}
-		lastWorked = cmp;
-		task.worked(work);
-	}
-
-	public void endTask() {
-		if (task != null) {
-			try {
-				task.done();
-			} finally {
-				task = null;
-			}
-		}
-	}
-
-	public boolean isCancelled() {
-		if (task != null)
-			return task.isCanceled();
-		return root.isCanceled();
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/GitCorePreferenceInitializer.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/GitCorePreferenceInitializer.java
deleted file mode 100644
index 4550b08..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/GitCorePreferenceInitializer.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2008, Roger C. Soares <rogersoares@intelinet.com.br>
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * Copyright (C) 2013, Matthias Sohn <matthias.sohn@sap.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core;
-
-import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
-import org.eclipse.core.runtime.preferences.DefaultScope;
-import org.eclipse.core.runtime.preferences.IEclipsePreferences;
-
-/** Initializes plugin preferences with default values. */
-public class GitCorePreferenceInitializer extends AbstractPreferenceInitializer {
-	private static final int MB = 1024 * 1024;
-
-	public void initializeDefaultPreferences() {
-		final IEclipsePreferences p  = DefaultScope.INSTANCE.getNode(Activator.getPluginId());
-
-		p.putInt(GitCorePreferences.core_packedGitWindowSize, 8 * 1024);
-		p.putInt(GitCorePreferences.core_packedGitLimit, 10 * MB);
-		p.putBoolean(GitCorePreferences.core_packedGitMMAP, false);
-		p.putInt(GitCorePreferences.core_deltaBaseCacheLimit, 10 * MB);
-		p.putInt(GitCorePreferences.core_streamFileThreshold, 50 * MB);
-		p.putBoolean(GitCorePreferences.core_autoShareProjects, true);
-		p.putBoolean(GitCorePreferences.core_autoIgnoreDerivedResources, true);
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/GitCorePreferences.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/GitCorePreferences.java
deleted file mode 100644
index 14c0a40..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/GitCorePreferences.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * Copyright (C) 2011, Robin Rosenberg
- * Copyright (C) 2013, Matthias Sohn <matthias.sohn@sap.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core;
-
-/** Preferences used by the core plugin. */
-public class GitCorePreferences {
-	/** */
-	public static final String core_packedGitWindowSize =
-		"core_packedGitWindowSize";  //$NON-NLS-1$
-	/** */
-	public static final String core_packedGitLimit =
-		"core_packedGitLimit";  //$NON-NLS-1$
-	/** */
-	public static final String core_packedGitMMAP =
-		"core_packedGitMMAP";  //$NON-NLS-1$
-	/** */
-	public static final String core_deltaBaseCacheLimit =
-		"core_deltaBaseCacheLimit";  //$NON-NLS-1$
-	/** */
-	public static final String core_streamFileThreshold =
-		"core_streamFileThreshold"; //$NON-NLS-1$
-	/** */
-	public static final String core_autoShareProjects =
-		"core_autoShareProjects";  //$NON-NLS-1$
-	/** */
-	public static final String core_autoIgnoreDerivedResources =
-		"core_autoIgnoreDerivedResources"; //$NON-NLS-1$
-	/** */
-	public static final String core_gitPrefix =
-		"core_gitPrefix"; //$NON-NLS-1$
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/GitMoveDeleteHook.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/GitMoveDeleteHook.java
deleted file mode 100644
index 4568ddd..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/GitMoveDeleteHook.java
+++ /dev/null
@@ -1,437 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
- * Copyright (C) 2007, Shawn O. Pearce <spearce@spearce.org>
- * Copyright (C) 2008, Google Inc.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Arrays;
-
-import org.eclipse.core.filesystem.URIUtil;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IProjectDescription;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.team.IMoveDeleteHook;
-import org.eclipse.core.resources.team.IResourceTree;
-import org.eclipse.core.runtime.Assert;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.egit.core.internal.indexdiff.IndexDiffCache;
-import org.eclipse.egit.core.internal.indexdiff.IndexDiffCacheEntry;
-import org.eclipse.egit.core.internal.indexdiff.IndexDiffData;
-import org.eclipse.egit.core.project.GitProjectData;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.jgit.dircache.DirCache;
-import org.eclipse.jgit.dircache.DirCacheBuilder;
-import org.eclipse.jgit.dircache.DirCacheEditor;
-import org.eclipse.jgit.dircache.DirCacheEntry;
-import org.eclipse.team.core.RepositoryProvider;
-import org.eclipse.team.core.TeamException;
-
-class GitMoveDeleteHook implements IMoveDeleteHook {
-	private static final boolean I_AM_DONE = true;
-
-	private static final boolean FINISH_FOR_ME = false;
-
-	private final GitProjectData data;
-
-	GitMoveDeleteHook(final GitProjectData d) {
-		Assert.isNotNull(d);
-		data = d;
-	}
-
-	public boolean deleteFile(final IResourceTree tree, final IFile file,
-			final int updateFlags, final IProgressMonitor monitor) {
-		// Linked resources are not files, hence not tracked by git
-		if (file.isLinked())
-			return false;
-
-		final boolean force = (updateFlags & IResource.FORCE) == IResource.FORCE;
-		if (!force && !tree.isSynchronized(file, IResource.DEPTH_ZERO))
-			return false;
-
-		final RepositoryMapping map = RepositoryMapping.getMapping(file);
-		if (map == null)
-			return false;
-
-		String repoRelativePath = map.getRepoRelativePath(file);
-		IndexDiffCache indexDiffCache = Activator.getDefault()
-				.getIndexDiffCache();
-		IndexDiffCacheEntry indexDiffCacheEntry = indexDiffCache
-				.getIndexDiffCacheEntry(map.getRepository());
-		IndexDiffData indexDiff = indexDiffCacheEntry.getIndexDiff();
-		if (indexDiff != null) {
-			if (indexDiff.getUntracked().contains(repoRelativePath))
-				return false;
-			if (indexDiff.getIgnoredNotInIndex().contains(repoRelativePath))
-				return false;
-		}
-		if (!file.exists())
-			return false;
-		if (file.isDerived())
-			return false;
-
-		DirCache dirc = null;
-		try {
-			dirc = map.getRepository().lockDirCache();
-			final int first = dirc.findEntry(repoRelativePath);
-			if (first < 0) {
-				dirc.unlock();
-				return false;
-			}
-
-			final DirCacheBuilder edit = dirc.builder();
-			if (first > 0)
-				edit.keep(0, first);
-			final int next = dirc.nextEntry(first);
-			if (next < dirc.getEntryCount())
-				edit.keep(next, dirc.getEntryCount() - next);
-			if (!edit.commit())
-				tree.failed(new Status(IStatus.ERROR, Activator.getPluginId(),
-						0, CoreText.MoveDeleteHook_operationError, null));
-			tree.standardDeleteFile(file, updateFlags, monitor);
-		} catch (IOException e) {
-			tree.failed(new Status(IStatus.ERROR, Activator.getPluginId(), 0,
-					CoreText.MoveDeleteHook_operationError, e));
-		} finally {
-			if (dirc != null)
-				dirc.unlock();
-		}
-		return true;
-	}
-
-	public boolean deleteFolder(final IResourceTree tree, final IFolder folder,
-			final int updateFlags, final IProgressMonitor monitor) {
-		// Deleting a GIT repository which is in use is a pretty bad idea. To
-		// delete disconnect the team provider first.
-		//
-		if (data.isProtected(folder)) {
-			return cannotModifyRepository(tree);
-		} else {
-			return FINISH_FOR_ME;
-		}
-	}
-
-	public boolean deleteProject(final IResourceTree tree,
-			final IProject project, final int updateFlags,
-			final IProgressMonitor monitor) {
-		// TODO: Note that eclipse thinks folders are real, while
-		// Git does not care.
-		return FINISH_FOR_ME;
-	}
-
-	public boolean moveFile(final IResourceTree tree, final IFile srcf,
-			final IFile dstf, final int updateFlags,
-			final IProgressMonitor monitor) {
-		final boolean force = (updateFlags & IResource.FORCE) == IResource.FORCE;
-		if (!force && !tree.isSynchronized(srcf, IResource.DEPTH_ZERO))
-			return false;
-
-		final RepositoryMapping srcm = RepositoryMapping.getMapping(srcf);
-		if (srcm == null)
-			return false;
-		final RepositoryMapping dstm = RepositoryMapping.getMapping(dstf);
-
-		DirCache sCache = null;
-		try {
-			sCache = srcm.getRepository().lockDirCache();
-			final String sPath = srcm.getRepoRelativePath(srcf);
-			final DirCacheEntry sEnt = sCache.getEntry(sPath);
-			if (sEnt == null)
-				return FINISH_FOR_ME;
-
-			if (!sEnt.isMerged()) {
-				tree.failed(new Status(IStatus.WARNING, Activator.getPluginId(),
-						CoreText.MoveDeleteHook_unmergedFileError));
-				return I_AM_DONE;
-			}
-
-			final DirCacheEditor sEdit = sCache.editor();
-			sEdit.add(new DirCacheEditor.DeletePath(sEnt));
-			if (dstm != null && dstm.getRepository() == srcm.getRepository()) {
-				final String dPath = srcm.getRepoRelativePath(dstf);
-				sEdit.add(new DirCacheEditor.PathEdit(dPath) {
-					@Override
-					public void apply(final DirCacheEntry dEnt) {
-						dEnt.copyMetaData(sEnt);
-					}
-				});
-			}
-			if (!sEdit.commit())
-				tree.failed(new Status(IStatus.ERROR, Activator.getPluginId(),
-						0, CoreText.MoveDeleteHook_operationError, null));
-
-			tree.standardMoveFile(srcf, dstf, updateFlags, monitor);
-		} catch (IOException e) {
-			tree.failed(new Status(IStatus.ERROR, Activator.getPluginId(), 0,
-					CoreText.MoveDeleteHook_operationError, e));
-		} finally {
-			if (sCache != null)
-				sCache.unlock();
-		}
-		return I_AM_DONE;
-	}
-
-	public boolean moveFolder(final IResourceTree tree, final IFolder srcf,
-			final IFolder dstf, final int updateFlags,
-			final IProgressMonitor monitor) {
-		final boolean force = (updateFlags & IResource.FORCE) == IResource.FORCE;
-		if (!force && !tree.isSynchronized(srcf, IResource.DEPTH_ZERO))
-			return false;
-
-		final RepositoryMapping srcm = RepositoryMapping.getMapping(srcf);
-		if (srcm == null)
-			return false;
-		final RepositoryMapping dstm = RepositoryMapping.getMapping(dstf);
-
-		try {
-			final String sPath = srcm.getRepoRelativePath(srcf);
-			if (dstm != null && dstm.getRepository() == srcm.getRepository()) {
-				final String dPath =
-					srcm.getRepoRelativePath(dstf) + "/"; //$NON-NLS-1$
-				MoveResult result = moveIndexContent(dPath, srcm, sPath);
-				switch (result) {
-				case SUCCESS:
-					break;
-				case FAILED:
-					tree.failed(new Status(IStatus.ERROR, Activator.getPluginId(),
-							0, CoreText.MoveDeleteHook_operationError, null));
-					return I_AM_DONE;
-				case UNTRACKED:
-					// we are not responsible for moving untracked files
-					return FINISH_FOR_ME;
-				case UNMERGED:
-					tree.failed(new Status(IStatus.WARNING, Activator.getPluginId(),
-							CoreText.MoveDeleteHook_unmergedFileInFolderError));
-					return I_AM_DONE;
-				}
-			}
-			tree.standardMoveFolder(srcf, dstf, updateFlags, monitor);
-		} catch (IOException e) {
-			tree.failed(new Status(IStatus.ERROR, Activator.getPluginId(), 0,
-					CoreText.MoveDeleteHook_operationError, e));
-		}
-		return true;
-	}
-
-	private void mapProject(final IProject source,
-			final IProjectDescription description,
-			final IProgressMonitor monitor, IPath gitDir) throws CoreException,
-			TeamException {
-		IProject destination = source.getWorkspace().getRoot()
-				.getProject(description.getName());
-		GitProjectData projectData = new GitProjectData(destination);
-		RepositoryMapping repositoryMapping = new RepositoryMapping(
-				destination, gitDir.toFile());
-		projectData.setRepositoryMappings(Arrays
-				.asList(repositoryMapping));
-		projectData.store();
-		GitProjectData.add(destination, projectData);
-		RepositoryProvider
-				.map(destination, GitProvider.class.getName());
-		destination.refreshLocal(IResource.DEPTH_INFINITE,
-				new SubProgressMonitor(monitor, 50));
-	}
-
-	private boolean unmapProject(final IResourceTree tree, final IProject source) {
-		// The Repository mapping does not support moving
-		// projects, so just disconnect/reconnect for now
-		try {
-			RepositoryProvider.unmap(source);
-		} catch (TeamException e) {
-			tree.failed(new Status(IStatus.ERROR, Activator
-					.getPluginId(), 0,
-					CoreText.MoveDeleteHook_operationError, e));
-					return true; // Do not let Eclipse complete the operation
-		}
-		return false;
-	}
-
-	public boolean moveProject(final IResourceTree tree, final IProject source,
-			final IProjectDescription description, final int updateFlags,
-			final IProgressMonitor monitor) {
-		final RepositoryMapping srcm = RepositoryMapping.getMapping(source);
-		if (srcm == null)
-			return false;
-		IPath newLocation = null;
-		if (description.getLocationURI() != null)
-			newLocation = URIUtil.toPath(description.getLocationURI());
-		else
-			newLocation = source.getWorkspace().getRoot().getLocation()
-					.append(description.getName());
-		IPath sourceLocation = source.getLocation();
-		// Prevent a serious error.
-		if (sourceLocation.isPrefixOf(newLocation)
-				&& sourceLocation.segmentCount() != newLocation.segmentCount()
-				&& !"true".equals(System.getProperty("egit.assume_307140_fixed"))) { //$NON-NLS-1$//$NON-NLS-2$
-			// Graceful handling of bug, i.e. refuse to destroy your code
-			tree.failed(new Status(
-					IStatus.ERROR,
-					Activator.getPluginId(),
-					0,
-					"Cannot move project. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=307140 (not resolved in 3.7)", //$NON-NLS-1$
-					null));
-			return true;
-		}
-		File newLocationFile = newLocation.toFile();
-		// check if new location is below the same repository
-		Path workTree = new Path(srcm.getRepository().getWorkTree().getAbsolutePath());
-		int matchingFirstSegments = workTree.matchingFirstSegments(newLocation);
-		if (matchingFirstSegments == workTree.segmentCount()) {
-			return moveProjectHelperMoveOnlyProject(tree, source, description, updateFlags,
-					monitor, srcm, newLocationFile);
-		} else {
-			int dstAboveSrcRepo = newLocation.matchingFirstSegments(RepositoryMapping
-					.getMapping(source).getGitDirAbsolutePath());
-			int srcAboveSrcRepo = sourceLocation.matchingFirstSegments(RepositoryMapping.getMapping(source).getGitDirAbsolutePath());
-			if (dstAboveSrcRepo > 0 && srcAboveSrcRepo > 0) {
-				return moveProjectHelperMoveRepo(tree, source, description, updateFlags, monitor,
-					srcm, newLocation, sourceLocation);
-			} else {
-				return FINISH_FOR_ME;
-			}
-		}
-	}
-
-	private boolean moveProjectHelperMoveOnlyProject(final IResourceTree tree,
-			final IProject source, final IProjectDescription description,
-			final int updateFlags, final IProgressMonitor monitor,
-			final RepositoryMapping srcm, File newLocationFile) {
-		final String sPath = srcm.getRepoRelativePath(source);
-		final String absoluteWorkTreePath = srcm.getRepository().getWorkTree().getAbsolutePath();
-		final String newLocationAbsolutePath = newLocationFile.getAbsolutePath();
-		final String dPath;
-		if (newLocationAbsolutePath.equals(absoluteWorkTreePath))
-			dPath = ""; //$NON-NLS-1$
-		else
-			dPath = new Path(
-					newLocationAbsolutePath.substring(absoluteWorkTreePath
-							.length() + 1) + "/").toPortableString(); //$NON-NLS-1$
-		try {
-			IPath gitDir = srcm.getGitDirAbsolutePath();
-			if (unmapProject(tree, source))
-				return true;
-
-			monitor.worked(100);
-
-			MoveResult result = moveIndexContent(dPath, srcm, sPath);
-			switch (result) {
-			case SUCCESS:
-				break;
-			case FAILED:
-				tree.failed(new Status(IStatus.ERROR, Activator
-						.getPluginId(), 0,
-						CoreText.MoveDeleteHook_operationError, null));
-				break;
-			case UNTRACKED:
-				// we are not responsible for moving untracked files
-				return FINISH_FOR_ME;
-			case UNMERGED:
-				tree.failed(new Status(IStatus.WARNING, Activator.getPluginId(),
-						CoreText.MoveDeleteHook_unmergedFileInFolderError));
-				return I_AM_DONE;
-			}
-
-			tree.standardMoveProject(source, description, updateFlags,
-					monitor);
-
-			// Reconnect
-			mapProject(
-					source.getWorkspace().getRoot()
-							.getProject(description.getName()),
-					description, monitor, gitDir);
-		} catch (IOException e) {
-			tree.failed(new Status(IStatus.ERROR, Activator.getPluginId(),
-					0, CoreText.MoveDeleteHook_operationError, e));
-		} catch (CoreException e) {
-			tree.failed(new Status(IStatus.ERROR, Activator.getPluginId(),
-					0, CoreText.MoveDeleteHook_operationError, e));
-		}
-		return true;
-	}
-
-	private boolean moveProjectHelperMoveRepo(final IResourceTree tree, final IProject source,
-			final IProjectDescription description, final int updateFlags,
-			final IProgressMonitor monitor, final RepositoryMapping srcm,
-			IPath newLocation, IPath sourceLocation) {
-		// Moving repo, we need to unplug the previous location and
-		// Re-plug it again with the new location.
-		IPath gitDir = srcm.getGitDirAbsolutePath();
-		if (unmapProject(tree, source))
-			return true; // Error information in tree
-
-		monitor.worked(100);
-
-		IPath relativeGitDir = gitDir.makeRelativeTo(sourceLocation);
-		tree.standardMoveProject(source, description, updateFlags,
-				monitor);
-
-		IPath newGitDir = newLocation.append(relativeGitDir);
-		// Reconnect
-		try {
-			mapProject(source, description, monitor, newGitDir);
-		} catch (CoreException e) {
-			tree.failed(new Status(IStatus.ERROR, Activator.getPluginId(),
-					0, CoreText.MoveDeleteHook_operationError, e));
-		}
-		return true; // We're done with the move
-	}
-
-	enum MoveResult { SUCCESS, FAILED, UNTRACKED, UNMERGED }
-
-	private MoveResult moveIndexContent(String dPath,
-			final RepositoryMapping srcm, final String sPath) throws IOException {
-
-		final DirCache sCache = srcm.getRepository().lockDirCache();
-		try {
-			final DirCacheEntry[] sEnt = sCache.getEntriesWithin(sPath);
-			if (sEnt.length == 0) {
-				sCache.unlock();
-				return MoveResult.UNTRACKED;
-			}
-
-			final DirCacheEditor sEdit = sCache.editor();
-			sEdit.add(new DirCacheEditor.DeleteTree(sPath));
-			final int sPathLen = sPath.length() == 0 ? sPath.length() : sPath
-					.length() + 1;
-			for (final DirCacheEntry se : sEnt) {
-				if (!se.isMerged())
-					return MoveResult.UNMERGED;
-				final String p = se.getPathString().substring(sPathLen);
-				sEdit.add(new DirCacheEditor.PathEdit(dPath + p) {
-					@Override
-					public void apply(final DirCacheEntry dEnt) {
-						dEnt.copyMetaData(se);
-					}
-				});
-			}
-			if (sEdit.commit())
-				return MoveResult.SUCCESS;
-			else
-				return MoveResult.FAILED;
-		} finally {
-			if (sCache != null)
-				sCache.unlock();
-		}
-	}
-
-	private boolean cannotModifyRepository(final IResourceTree tree) {
-		tree.failed(new Status(IStatus.ERROR, Activator.getPluginId(), 0,
-				CoreText.MoveDeleteHook_cannotModifyFolder, null));
-		return I_AM_DONE;
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/GitProjectSetCapability.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/GitProjectSetCapability.java
deleted file mode 100644
index 836081a..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/GitProjectSetCapability.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2009, Mykola Nikishov <mn@mn.com.ua>
- * Copyright (C) 2011, Robin Stocker <robin@nibor.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Manuel Doninger <manuel.doninger@googlemail.com>
- *     Tomasz Zarna <Tomasz.Zarna@pl.ibm.com>
- *******************************************************************************/
-package org.eclipse.egit.core;
-
-import java.io.IOException;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IWorkspace;
-import org.eclipse.core.resources.IWorkspaceRunnable;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.egit.core.internal.GitURI;
-import org.eclipse.egit.core.internal.ProjectReferenceImporter;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.jgit.lib.ConfigConstants;
-import org.eclipse.jgit.lib.StoredConfig;
-import org.eclipse.osgi.util.NLS;
-import org.eclipse.team.core.ProjectSetCapability;
-import org.eclipse.team.core.ProjectSetSerializationContext;
-import org.eclipse.team.core.TeamException;
-
-/**
- * Capability for exporting and importing projects shared with Git as part of a
- * team project set.
- */
-public final class GitProjectSetCapability extends ProjectSetCapability {
-
-	private static final String VERSION = "1.0"; //$NON-NLS-1$
-
-	@Override
-	public String[] asReference(IProject[] projects,
-			ProjectSetSerializationContext context, IProgressMonitor monitor)
-			throws TeamException {
-		String[] references = new String[projects.length];
-		for (int i = 0; i < projects.length; i++)
-			references[i] = asReference(projects[i]);
-		return references;
-	}
-
-	private String asReference(IProject project) throws TeamException {
-		RepositoryMapping mapping = RepositoryMapping.getMapping(project);
-		String branch;
-		try {
-			branch = mapping.getRepository().getBranch();
-		} catch (IOException e) {
-			throw new TeamException(NLS.bind(
-					CoreText.GitProjectSetCapability_ExportCouldNotGetBranch,
-					project.getName()));
-		}
-		StoredConfig config = mapping.getRepository().getConfig();
-		String remote = config.getString(ConfigConstants.CONFIG_BRANCH_SECTION,
-				branch, ConfigConstants.CONFIG_KEY_REMOTE);
-		String url = config.getString(ConfigConstants.CONFIG_REMOTE_SECTION,
-				remote, ConfigConstants.CONFIG_KEY_URL);
-		if (url == null)
-			throw new TeamException(NLS.bind(
-					CoreText.GitProjectSetCapability_ExportNoRemote,
-					project.getName()));
-
-		String projectPath = mapping.getRepoRelativePath(project);
-		if (projectPath.equals("")) //$NON-NLS-1$
-			projectPath = "."; //$NON-NLS-1$
-
-		return asReference(url, branch, projectPath);
-	}
-
-	private String asReference(String url, String branch, String projectPath) {
-		StringBuilder sb = new StringBuilder();
-
-		sb.append(VERSION);
-		sb.append(ProjectReference.SEPARATOR);
-		sb.append(url);
-		sb.append(ProjectReference.SEPARATOR);
-		sb.append(branch);
-		sb.append(ProjectReference.SEPARATOR);
-		sb.append(projectPath);
-
-		return sb.toString();
-	}
-
-	@Override
-	public IProject[] addToWorkspace(final String[] referenceStrings,
-			final ProjectSetSerializationContext context,
-			final IProgressMonitor monitor) throws TeamException {
-		final ArrayList<IProject> importedProjects = new ArrayList<IProject>();
-
-		try{
-			ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
-				public void run(IProgressMonitor wsOpMonitor) throws CoreException {
-					ProjectReferenceImporter importer = new ProjectReferenceImporter(referenceStrings);
-					List<IProject> p = importer.run(wsOpMonitor);
-					importedProjects.addAll(p);
-				}
-			}, ResourcesPlugin.getWorkspace().getRoot(), IWorkspace.AVOID_UPDATE, monitor);
-		} catch (CoreException e) {
-			throw TeamException.asTeamException(e);
-		}
-		final IProject[] result = importedProjects
-				.toArray(new IProject[importedProjects.size()]);
-		return result;
-	}
-
-	@Override
-	public String asReference(URI uri, String projectName) {
-		GitURI gitURI = new GitURI(uri);
-		return asReference(gitURI.getRepository().toString(), gitURI.getTag(), gitURI.getPath().toString());
-	}
-}
\ No newline at end of file
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/GitProvider.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/GitProvider.java
deleted file mode 100644
index d18ff90..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/GitProvider.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core;
-
-import java.io.IOException;
-
-import org.eclipse.core.resources.IResourceRuleFactory;
-import org.eclipse.core.resources.team.IMoveDeleteHook;
-import org.eclipse.core.resources.team.ResourceRuleFactory;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.egit.core.internal.storage.GitFileHistoryProvider;
-import org.eclipse.egit.core.project.GitProjectData;
-import org.eclipse.team.core.RepositoryProvider;
-import org.eclipse.team.core.history.IFileHistoryProvider;
-
-/**
- * The Team provider class for a Git repository.
- */
-public class GitProvider extends RepositoryProvider {
-
-	/**
-	 * Id of repository provider
-	 *
-	 * @see #getID()
-	 */
-	public static final String ID = "org.eclipse.egit.core.GitProvider"; //$NON-NLS-1$
-
-	private GitProjectData data;
-
-	private GitMoveDeleteHook hook;
-
-	private GitFileHistoryProvider historyProvider;
-
-	private final IResourceRuleFactory resourceRuleFactory = new GitResourceRuleFactory();
-
-	public String getID() {
-		return ID;
-	}
-
-	public void configureProject() throws CoreException {
-		getData().markTeamPrivateResources();
-	}
-
-	public void deconfigure() throws CoreException {
-		try {
-			GitProjectData.delete(getProject());
-		} catch (IOException e) {
-			throw new CoreException(new Status(IStatus.ERROR,
-					Activator.getPluginId(), e.getMessage(), e));
-		}
-	}
-
-	public boolean canHandleLinkedResources() {
-		return true;
-	}
-
-	@Override
-	public boolean canHandleLinkedResourceURI() {
-		return true;
-	}
-
-	public synchronized IMoveDeleteHook getMoveDeleteHook() {
-		if (hook == null) {
-			GitProjectData _data = getData();
-			if (_data != null)
-				hook = new GitMoveDeleteHook(_data);
-		}
-		return hook;
-	}
-
-	/**
-	 * @return information about the mapping of an Eclipse project
-	 * to a Git repository.
-	 */
-	public synchronized GitProjectData getData() {
-		if (data == null) {
-			data = GitProjectData.get(getProject());
-		}
-		return data;
-	}
-
-	public synchronized IFileHistoryProvider getFileHistoryProvider() {
-		if (historyProvider == null) {
-			historyProvider = new GitFileHistoryProvider();
-		}
-		return historyProvider;
-	}
-
-	@Override
-	public IResourceRuleFactory getRuleFactory() {
-		return resourceRuleFactory;
-	}
-
-	private static class GitResourceRuleFactory extends ResourceRuleFactory {
-		// Use the default rule factory instead of the
-		// pessimistic one by default.
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/GitTag.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/GitTag.java
deleted file mode 100644
index 42581a3..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/GitTag.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
- * Copyright (C) 2007, Shawn O. Pearce <spearce@spearce.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core;
-
-import org.eclipse.team.core.history.ITag;
-
-/**
- * A representation of a Git tag in Eclipse.
- */
-public class GitTag implements ITag {
-
-	private String name;
-
-	/**
-	 * Construct a GitTag object with a given name.
-	 *
-	 * @param name the Git tag name
-	 */
-	public GitTag(String name) {
-		this.name = name;
-	}
-
-	public String getName() {
-		return name;
-	}
-
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/IteratorService.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/IteratorService.java
deleted file mode 100644
index 99557a3..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/IteratorService.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2010, 2012 Jens Baumgart <jens.baumgart@sap.com> and others.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core;
-
-import java.io.File;
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IWorkspaceRoot;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.treewalk.WorkingTreeIterator;
-
-/**
- * IteratorService is a utility class for providing the right
- * {@link WorkingTreeIterator} iterator for a given folder.
- *
- */
-public class IteratorService {
-
-	/**
-	 * Creates a {@link WorkingTreeIterator} for a tree walk starting on the
-	 * repository work tree folder.
-	 *
-	 * @param repository
-	 * @return <li>a {@link ContainerTreeIterator} if the work tree folder of
-	 *         the given repository resides in a project shared with Git <li>an
-	 *         {@link AdaptableFileTreeIterator} otherwise <li>{@code null} if the
-	 *         workspace is closed.
-	 */
-	public static WorkingTreeIterator createInitialIterator(
-			Repository repository) {
-		IWorkspaceRoot root;
-		try {
-			root = ResourcesPlugin.getWorkspace().getRoot();
-		} catch (IllegalStateException e) {
-			// workspace is closed
-			return null;
-		}
-		IContainer container = findContainer(root, repository.getWorkTree());
-		if (container != null)
-			return new ContainerTreeIterator(repository, container);
-		return new AdaptableFileTreeIterator(repository, root);
-	}
-
-	/**
-	 * The method searches a container resource related to the given file. The
-	 * container must reside in a project that is shared with Git. Linked folders
-	 * are ignored.
-	 *
-	 * @param root
-	 *            the workspace root
-	 * @param file
-	 * @return a container that matches the description above or null if such a
-	 *         container does not exist
-	 */
-	public static IContainer findContainer(IWorkspaceRoot root, File file) {
-		if (!file.isDirectory())
-			throw new IllegalArgumentException(
-					"file " + file.getAbsolutePath() + " is no directory"); //$NON-NLS-1$//$NON-NLS-2$
-		final IContainer[] containers = root.findContainersForLocationURI(file
-				.toURI());
-		for (IContainer container : containers)
-			if (container.isAccessible()
-					&& !container.isLinked(IResource.CHECK_ANCESTORS)
-					&& isProjectSharedWithGit(container))
-				return container;
-		return null;
-	}
-
-	private static boolean isProjectSharedWithGit(IContainer container) {
-		return RepositoryMapping.getMapping(container) != null;
-	}
-
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/JobFamilies.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/JobFamilies.java
deleted file mode 100644
index 698b7d4..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/JobFamilies.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2011, 2013 Matthias Sohn <matthias.sohn@sap.com> and others.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core;
-
-/**
- * Job families of EGit jobs. May be used in tests to join job execution.
- *
- */
-public class JobFamilies {
-
-	/**
-	 * Job family for Repository changed job
-	 */
-	public static final Object REPOSITORY_CHANGED = new Object();
-
-	/**
-	 * Job family for Index Diff Cache update
-	 */
-	public static final Object INDEX_DIFF_CACHE_UPDATE = new Object();
-
-	/**
-	 * Job family for auto share job
-	 */
-	public static final Object AUTO_SHARE = new Object();
-
-	/**
-	 * Job family for auto ignore job
-	 */
-	public static final Object AUTO_IGNORE = new Object();
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/ProjectReference.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/ProjectReference.java
deleted file mode 100644
index d72db6c..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/ProjectReference.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2009, Mykola Nikishov <mn@mn.com.ua>
- * Copyright (C) 2011, Robin Stocker <robin@nibor.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     Manuel Doninger <manuel.doninger@googlemail.com>
- *******************************************************************************/
-package org.eclipse.egit.core;
-
-import java.net.URISyntaxException;
-import java.util.regex.Pattern;
-
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.transport.URIish;
-import org.eclipse.osgi.util.NLS;
-
-/**
- * ProjectReference for Team project sets
- */
-public final class ProjectReference {
-
-	private static final String DEFAULT_BRANCH = Constants.MASTER;
-
-	/**
-	 * the version of the reference string
-	 */
-	private String version;
-
-	/**
-	 * a relative path (from the repository root) to a project
-	 */
-	private String projectDir;
-
-	/**
-	 * <code>repository</code> parameter
-	 */
-	private URIish repository;
-
-	/**
-	 * the remote branch that will be checked out, see <code>--branch</code>
-	 * option
-	 */
-	private String branch = DEFAULT_BRANCH;
-
-	/**
-	 * use this name instead of using the remote name origin to keep track
-	 * of the upstream repository, see <code>--origin</code> option.
-	 */
-	private String origin = Constants.DEFAULT_REMOTE_NAME;
-
-	static final String SEPARATOR = ","; //$NON-NLS-1$
-
-	/**
-	 * @param reference
-	 * @throws URISyntaxException
-	 * @throws IllegalArgumentException
-	 */
-	@SuppressWarnings("boxing")
-	public ProjectReference(final String reference) throws URISyntaxException, IllegalArgumentException {
-		final String[] tokens = reference.split(Pattern.quote(ProjectReference.SEPARATOR));
-		if (tokens.length != 4)
-			throw new IllegalArgumentException(NLS.bind(
-					CoreText.ProjectReference_InvalidTokensCount, new Object[] {
-							4, tokens.length, tokens }));
-
-		this.version = tokens[0];
-		this.repository = new URIish(tokens[1]);
-		if (!"".equals(tokens[2])) //$NON-NLS-1$
-			this.branch = tokens[2];
-		this.projectDir = tokens[3];
-	}
-
-	/**
-	 * @return <code>repository</code> parameter
-	 */
-	public URIish getRepository() {
-		return repository;
-	}
-
-	/**
-	 * @return the remote branch that will be checked out, see <code>--branch</code>
-	 * option
-	 */
-	public String getBranch() {
-		return branch;
-	}
-
-	/**
-	 * @return name of the upstream repository
-	 */
-	public String getOrigin() {
-		return origin;
-	}
-
-	/**
-	 * @return a relative path (from the repository root) to a project
-	 */
-	public String getProjectDir() {
-		return projectDir;
-	}
-
-	String getVersion() {
-		return version;
-	}
-
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = 1;
-		result = prime * result + ((branch == null) ? 0 : branch.hashCode());
-		result = prime * result
-				+ ((projectDir == null) ? 0 : projectDir.hashCode());
-		result = prime * result
-				+ ((repository == null) ? 0 : repository.hashCode());
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (obj == null)
-			return false;
-		if (!(obj instanceof ProjectReference))
-			return false;
-		ProjectReference other = (ProjectReference) obj;
-		if (branch == null) {
-			if (other.branch != null)
-				return false;
-		} else if (!branch.equals(other.branch))
-			return false;
-		if (projectDir == null) {
-			if (other.projectDir != null)
-				return false;
-		} else if (!projectDir.equals(other.projectDir))
-			return false;
-		if (repository == null) {
-			if (other.repository != null)
-				return false;
-		} else if (!repository.equals(other.repository))
-			return false;
-		return true;
-	}
-}
\ No newline at end of file
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/RepositoryCache.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/RepositoryCache.java
deleted file mode 100644
index 2ff0867..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/RepositoryCache.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2010, Jens Baumgart <jens.baumgart@sap.com>
- * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * Copyright (C) 2008, Google Inc.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core;
-
-import java.io.File;
-import java.io.IOException;
-import java.lang.ref.Reference;
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.internal.storage.file.FileRepository;
-
-/**
- * Central cache for Repository instances
- *
- */
-public class RepositoryCache {
-	private final Map<File, Reference<Repository>> repositoryCache = new HashMap<File, Reference<Repository>>();
-
-	RepositoryCache() {
-		// package private constructor
-	}
-
-	/**
-	 *
-	 * @param gitDir
-	 * @return an existing instance of Repository for <code>gitDir</code> or a
-	 *         new one if no Repository instance for <code>gitDir</code> exists
-	 *         in the cache.
-	 * @throws IOException
-	 */
-	public synchronized Repository lookupRepository(final File gitDir)
-			throws IOException {
-		prune(repositoryCache);
-		Reference<Repository> r = repositoryCache.get(gitDir);
-		Repository d = r != null ? r.get() : null;
-		if (d == null) {
-			d = new FileRepository(gitDir);
-			repositoryCache.put(gitDir, new WeakReference<Repository>(d));
-		}
-		return d;
-	}
-
-	/**
-	 * @return all Repository instances contained in the cache
-	 */
-	public synchronized Repository[] getAllRepositories() {
-		prune(repositoryCache);
-		List<Repository> repositories = new ArrayList<Repository>();
-		for (Reference<Repository> reference : repositoryCache.values()) {
-			repositories.add(reference.get());
-		}
-		return repositories.toArray(new Repository[repositories.size()]);
-	}
-
-	private static void prune(Map<File, Reference<Repository>> map) {
-		for (final Iterator<Map.Entry<File, Reference<Repository>>> i = map.entrySet()
-				.iterator(); i.hasNext();) {
-			Repository repository = i.next().getValue().get();
-			if (repository == null
-					|| !repository.getDirectory().exists())
-				i.remove();
-		}
-	}
-
-	/**
-	 * TESTING ONLY!
-	 * Unit tests can use this method to get a clean beginning state
-	 */
-	public void clear() {
-		repositoryCache.clear();
-	}
-
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/RepositoryUtil.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/RepositoryUtil.java
deleted file mode 100644
index 7479960..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/RepositoryUtil.java
+++ /dev/null
@@ -1,538 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010 SAP AG.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *    Mathias Kinzler (SAP AG) - initial implementation
- *******************************************************************************/
-package org.eclipse.egit.core;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.StringTokenizer;
-import java.util.TreeSet;
-
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.preferences.IEclipsePreferences;
-import org.eclipse.core.runtime.preferences.InstanceScope;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.jgit.api.MergeCommand.FastForwardMode;
-import org.eclipse.jgit.errors.IncorrectObjectTypeException;
-import org.eclipse.jgit.lib.ConfigConstants;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.lib.FileMode;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.lib.RepositoryCache.FileKey;
-import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.jgit.revwalk.RevObject;
-import org.eclipse.jgit.revwalk.RevTag;
-import org.eclipse.jgit.revwalk.RevWalk;
-import org.eclipse.jgit.internal.storage.file.CheckoutEntry;
-import org.eclipse.jgit.internal.storage.file.ReflogEntry;
-import org.eclipse.jgit.internal.storage.file.ReflogReader;
-import org.eclipse.jgit.treewalk.FileTreeIterator;
-import org.eclipse.jgit.treewalk.TreeWalk;
-import org.eclipse.jgit.treewalk.WorkingTreeIterator;
-import org.eclipse.jgit.treewalk.filter.PathFilter;
-import org.eclipse.jgit.util.FS;
-import org.osgi.service.prefs.BackingStoreException;
-
-/**
- * Utility class for handling Repositories in the UI.
- */
-public class RepositoryUtil {
-
-	/** The preferences to store the directories known to the Git Repositories view */
-	public static final String PREFS_DIRECTORIES = "GitRepositoriesView.GitDirectories"; //$NON-NLS-1$
-
-	private final Map<String, Map<String, String>> commitMappingCache = new HashMap<String, Map<String, String>>();
-
-	private final Map<String, String> repositoryNameCache = new HashMap<String, String>();
-
-	private final IEclipsePreferences prefs = InstanceScope.INSTANCE
-			.getNode(Activator.getPluginId());
-
-	/**
-	 * Clients should obtain an instance from {@link Activator}
-	 */
-	RepositoryUtil() {
-		// nothing
-	}
-
-	/**
-	 * Used by {@link Activator}
-	 */
-	void dispose() {
-		commitMappingCache.clear();
-		repositoryNameCache.clear();
-	}
-
-	/**
-	 * Tries to map a commit to a symbolic reference.
-	 * <p>
-	 * This value will be cached for the given commit ID unless refresh is
-	 * specified. The return value will be the full name, e.g.
-	 * "refs/remotes/someBranch", "refs/tags/v.1.0"
-	 * <p>
-	 * Since this mapping is not unique, the following precedence rules are
-	 * used:
-	 * <ul>
-	 * <li>Tags take precedence over branches</li>
-	 * <li>Local branches take preference over remote branches</li>
-	 * <li>Newer references take precedence over older ones where time stamps
-	 * are available. Use commiter time stamp from commit if no stamp can be
-	 * found on the tag</li>
-	 * <li>If there are still ambiguities, the reference name with the highest
-	 * lexicographic value will be returned</li>
-	 * </ul>
-	 *
-	 * @param repository
-	 *            the {@link Repository}
-	 * @param commitId
-	 *            a commit
-	 * @param refresh
-	 *            if true, the cache will be invalidated
-	 * @return the symbolic reference, or <code>null</code> if no such reference
-	 *         can be found
-	 */
-	public String mapCommitToRef(Repository repository, String commitId,
-			boolean refresh) {
-		synchronized (commitMappingCache) {
-
-			if (!ObjectId.isId(commitId)) {
-				return null;
-			}
-
-			try {
-				ReflogReader reflogReader = repository.getReflogReader(Constants.HEAD);
-				if (reflogReader != null) {
-					List<ReflogEntry> lastEntry = reflogReader.getReverseEntries();
-					for (ReflogEntry entry : lastEntry) {
-						if (entry.getNewId().name().equals(commitId)) {
-							CheckoutEntry checkoutEntry = entry.parseCheckout();
-							if (checkoutEntry != null) {
-								Ref ref = repository.getRef(checkoutEntry.getToBranch());
-								if (ref != null)
-									ref = repository.peel(ref);
-								if (ref != null) {
-									ObjectId id = ref.getPeeledObjectId();
-									if (id != null && id.getName().equals(commitId))
-										return checkoutEntry.getToBranch();
-								}
-							}
-						}
-					}
-				}
-			} catch (IOException e) {
-				// ignore here
-			}
-
-			Map<String, String> cacheEntry = commitMappingCache.get(repository
-					.getDirectory().toString());
-			if (!refresh && cacheEntry != null
-					&& cacheEntry.containsKey(commitId)) {
-				// this may be null in fact
-				return cacheEntry.get(commitId);
-			}
-			if (cacheEntry == null) {
-				cacheEntry = new HashMap<String, String>();
-				commitMappingCache.put(repository.getDirectory().getPath(),
-						cacheEntry);
-			} else {
-				cacheEntry.clear();
-			}
-
-			Map<String, Date> tagMap = new HashMap<String, Date>();
-			try {
-				RevWalk rw = new RevWalk(repository);
-				Map<String, Ref> tags = repository.getRefDatabase().getRefs(
-						Constants.R_TAGS);
-				for (Ref tagRef : tags.values()) {
-					RevObject any = rw.parseAny(repository.resolve(tagRef.getName()));
-					if (any instanceof RevTag) {
-						RevTag tag = (RevTag) any;
-						if (tag.getObject().name().equals(commitId)) {
-							Date timestamp;
-							if (tag.getTaggerIdent() != null) {
-								timestamp = tag.getTaggerIdent().getWhen();
-							} else {
-								try {
-									RevCommit commit = rw.parseCommit(tag.getObject());
-									timestamp = commit.getCommitterIdent().getWhen();
-								} catch (IncorrectObjectTypeException e) {
-									// not referencing a comit.
-									timestamp = null;
-								}
-							}
-							tagMap.put(tagRef.getName(), timestamp);
-						}
-					} else if (any instanceof RevCommit) {
-						RevCommit commit = ((RevCommit)any);
-						if (commit.name().equals(commitId))
-							tagMap.put(tagRef.getName(), commit.getCommitterIdent().getWhen());
-					} // else ignore here
-				}
-			} catch (IOException e) {
-				// ignore here
-			}
-
-			String cacheValue = null;
-
-			if (!tagMap.isEmpty()) {
-				// we try to obtain the "latest" tag
-				Date compareDate = new Date(0);
-				for (Map.Entry<String, Date> tagEntry : tagMap.entrySet()) {
-					if (tagEntry.getValue() != null
-							&& tagEntry.getValue().after(compareDate)) {
-						compareDate = tagEntry.getValue();
-						cacheValue = tagEntry.getKey();
-					}
-				}
-				// if we don't have time stamps, we sort
-				if (cacheValue == null) {
-					String compareString = ""; //$NON-NLS-1$
-					for (String tagName : tagMap.keySet()) {
-						if (tagName.compareTo(compareString) >= 0) {
-							cacheValue = tagName;
-							compareString = tagName;
-						}
-					}
-				}
-			}
-
-			if (cacheValue == null) {
-				// we didnt't find a tag, so let's look for local branches
-				Set<String> branchNames = new TreeSet<String>();
-				// put this into a sorted set
-				try {
-					Map<String, Ref> remoteBranches = repository
-							.getRefDatabase().getRefs(Constants.R_HEADS);
-					for (Ref branch : remoteBranches.values()) {
-						if (branch.getObjectId().name().equals(commitId)) {
-							branchNames.add(branch.getName());
-						}
-					}
-				} catch (IOException e) {
-					// ignore here
-				}
-				if (!branchNames.isEmpty()) {
-					// get the last (sorted) entry
-					cacheValue = branchNames.toArray(new String[branchNames
-							.size()])[branchNames.size() - 1];
-				}
-			}
-
-			if (cacheValue == null) {
-				// last try: remote branches
-				Set<String> branchNames = new TreeSet<String>();
-				// put this into a sorted set
-				try {
-					Map<String, Ref> remoteBranches = repository
-							.getRefDatabase().getRefs(Constants.R_REMOTES);
-					for (Ref branch : remoteBranches.values()) {
-						if (branch.getObjectId().name().equals(commitId)) {
-							branchNames.add(branch.getName());
-						}
-					}
-					if (!branchNames.isEmpty()) {
-						// get the last (sorted) entry
-						cacheValue = branchNames.toArray(new String[branchNames
-								.size()])[branchNames.size() - 1];
-					}
-				} catch (IOException e) {
-					// ignore here
-				}
-			}
-			cacheEntry.put(commitId, cacheValue);
-			return cacheValue;
-		}
-	}
-
-	/**
-	 * Return a cached UI "name" for a Repository
-	 * <p>
-	 * This uses the name of the parent of the repository's directory.
-	 *
-	 * @param repository
-	 * @return the name
-	 */
-	public String getRepositoryName(final Repository repository) {
-		File gitDir = repository.getDirectory();
-		if (gitDir == null)
-			return ""; //$NON-NLS-1$
-
-		// Use parent file for non-bare repositories
-		if (!repository.isBare()) {
-			gitDir = gitDir.getParentFile();
-			if (gitDir == null)
-				return ""; //$NON-NLS-1$
-		}
-
-		synchronized (repositoryNameCache) {
-			final String path = gitDir.getPath().toString();
-			String name = repositoryNameCache.get(path);
-			if (name != null)
-				return name;
-			name = gitDir.getName();
-			repositoryNameCache.put(path, name);
-			return name;
-		}
-	}
-
-	/**
-	 * @return the underlying preferences
-	 */
-	public IEclipsePreferences getPreferences() {
-		return prefs;
-	}
-
-	private Set<String> getRepositories() {
-		String dirs;
-		synchronized (prefs) {
-			dirs = prefs.get(PREFS_DIRECTORIES, ""); //$NON-NLS-1$
-		}
-		if (dirs == null || dirs.length() == 0)
-			return Collections.emptySet();
-		Set<String> configuredStrings = new HashSet<String>();
-		StringTokenizer tok = new StringTokenizer(dirs, File.pathSeparator);
-		while (tok.hasMoreTokens())
-			configuredStrings.add(tok.nextToken());
-		return configuredStrings;
-	}
-
-	/**
-	 *
-	 * @return the list of configured Repository paths; will be sorted
-	 */
-	public List<String> getConfiguredRepositories() {
-		final List<String> repos = new ArrayList<String>(getRepositories());
-		Collections.sort(repos);
-		return repos;
-	}
-
-	private String getPath(File repositoryDir) {
-		try {
-			return repositoryDir.getCanonicalPath();
-		} catch (IOException e) {
-			return repositoryDir.getAbsolutePath();
-		}
-	}
-
-	/**
-	 *
-	 * @param repositoryDir
-	 *            the Repository path
-	 * @return <code>true</code> if the repository path was not yet configured
-	 * @throws IllegalArgumentException
-	 *             if the path does not "look" like a Repository
-	 */
-	public boolean addConfiguredRepository(File repositoryDir)
-			throws IllegalArgumentException {
-		synchronized (prefs) {
-
-			if (!FileKey.isGitRepository(repositoryDir, FS.DETECTED))
-				throw new IllegalArgumentException();
-
-			String dirString = getPath(repositoryDir);
-
-			List<String> dirStrings = getConfiguredRepositories();
-			if (dirStrings.contains(dirString)) {
-				return false;
-			} else {
-				Set<String> dirs = new HashSet<String>();
-				dirs.addAll(dirStrings);
-				dirs.add(dirString);
-				saveDirs(dirs);
-				return true;
-			}
-		}
-	}
-
-	/**
-	 * @param file
-	 * @return <code>true</code> if the configuration was changed by the remove
-	 */
-	public boolean removeDir(File file) {
-		synchronized (prefs) {
-
-			String dir = getPath(file);
-
-			Set<String> dirStrings = new HashSet<String>();
-			dirStrings.addAll(getConfiguredRepositories());
-			if (dirStrings.remove(dir)) {
-				saveDirs(dirStrings);
-				return true;
-			}
-			return false;
-		}
-	}
-
-	private void saveDirs(Set<String> gitDirStrings) {
-		StringBuilder sb = new StringBuilder();
-		for (String gitDirString : gitDirStrings) {
-			sb.append(gitDirString);
-			sb.append(File.pathSeparatorChar);
-		}
-
-		prefs.put(PREFS_DIRECTORIES, sb.toString());
-		try {
-			prefs.flush();
-		} catch (BackingStoreException e) {
-			IStatus error = new Status(IStatus.ERROR, Activator.getPluginId(),
-					e.getMessage(), e);
-			Activator.getDefault().getLog().log(error);
-		}
-	}
-
-	/**
-	 * Does the collection of repository returned by
-	 * {@link #getConfiguredRepositories()} contain the given repository?
-	 *
-	 * @param repository
-	 * @return true if contains repository, false otherwise
-	 */
-	public boolean contains(final Repository repository) {
-		return contains(getPath(repository.getDirectory()));
-	}
-
-	/**
-	 * Does the collection of repository returned by
-	 * {@link #getConfiguredRepositories()} contain the given repository
-	 * directory?
-	 *
-	 * @param repositoryDir
-	 * @return true if contains repository directory, false otherwise
-	 */
-	public boolean contains(final String repositoryDir) {
-		return getRepositories().contains(repositoryDir);
-	}
-
-	/**
-	 * Get short branch text for given repository
-	 *
-	 * @param repository
-	 * @return short branch text
-	 * @throws IOException
-	 */
-	public String getShortBranch(Repository repository) throws IOException {
-		Ref head = repository.getRef(Constants.HEAD);
-		if (head == null || head.getObjectId() == null)
-			return CoreText.RepositoryUtil_noHead;
-
-		if (head.isSymbolic())
-			return repository.getBranch();
-
-		String id = head.getObjectId().name();
-		String ref = mapCommitToRef(repository, id, false);
-		if (ref != null)
-			return Repository.shortenRefName(ref) + ' ' + id.substring(0, 7);
-		else
-			return id.substring(0, 7);
-	}
-
-	/**
-	 * Resolve HEAD and parse the commit. Returns null if HEAD does not exist or
-	 * could not be parsed.
-	 * <p>
-	 * Only use this if you don't already have to work with a RevWalk.
-	 *
-	 * @param repository
-	 * @return the commit or null if HEAD does not exist or could not be parsed.
-	 * @since 2.2
-	 */
-	public RevCommit parseHeadCommit(Repository repository) {
-		RevWalk walk = null;
-		try {
-			Ref head = repository.getRef(Constants.HEAD);
-			if (head == null || head.getObjectId() == null)
-				return null;
-
-			walk = new RevWalk(repository);
-			RevCommit commit = walk.parseCommit(head.getObjectId());
-			return commit;
-		} catch (IOException e) {
-			return null;
-		} finally {
-			if (walk != null)
-				walk.release();
-		}
-	}
-
-	/**
-	 * Checks if resource with given path is to be ignored.
-	 *
-	 * @param path
-	 *            Path to be checked
-	 * @return true if the path matches an ignore rule or no repository mapping
-	 *         could be found, false otherwise
-	 * @throws IOException
-	 * @since 2.3
-	 */
-	public static boolean isIgnored(IPath path) throws IOException {
-		RepositoryMapping mapping = RepositoryMapping.getMapping(path);
-		if (mapping == null)
-			return true; // Linked resources may not be mapped
-		Repository repository = mapping.getRepository();
-		String repoRelativePath = mapping.getRepoRelativePath(path);
-		TreeWalk walk = new TreeWalk(repository);
-		try {
-			walk.addTree(new FileTreeIterator(repository));
-			walk.setFilter(PathFilter.create(repoRelativePath));
-			while (walk.next()) {
-				WorkingTreeIterator workingTreeIterator = walk.getTree(0,
-						WorkingTreeIterator.class);
-				if (walk.getPathString().equals(repoRelativePath))
-					return workingTreeIterator.isEntryIgnored();
-				if (workingTreeIterator.getEntryFileMode()
-						.equals(FileMode.TREE))
-					walk.enterSubtree();
-			}
-		} finally {
-			walk.release();
-		}
-		return false;
-	}
-
-	/**
-	 * Get the fast-forward setting for current branch on the given repository.
-	 *
-	 * @param repository
-	 *            the repository to check
-	 * @return the fast-forward mode for the current branch
-	 * @since 2.4
-	 */
-	public FastForwardMode getFastForwardMode(Repository repository) {
-		FastForwardMode ffmode = FastForwardMode.valueOf(repository.getConfig()
-				.getEnum(ConfigConstants.CONFIG_KEY_MERGE, null,
-						ConfigConstants.CONFIG_KEY_FF,
-						FastForwardMode.Merge.TRUE));
-		ffmode = repository.getConfig().getEnum(
-				ConfigConstants.CONFIG_BRANCH_SECTION,
-				getCurrentBranch(repository),
-				ConfigConstants.CONFIG_KEY_MERGEOPTIONS, ffmode);
-		return ffmode;
-	}
-
-	private String getCurrentBranch(Repository repository) {
-		try {
-			return repository.getBranch();
-		} catch (IOException e) {
-			return null;
-		}
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/RevUtils.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/RevUtils.java
deleted file mode 100644
index 89b8c00..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/RevUtils.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
- * Copyright (C) 2012, Robin Stocker <robin@nibor.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core;
-
-import java.io.IOException;
-import java.util.Collection;
-
-import org.eclipse.core.runtime.Assert;
-import org.eclipse.jgit.lib.AnyObjectId;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.jgit.revwalk.RevWalk;
-import org.eclipse.jgit.revwalk.filter.RevFilter;
-
-/**
- * Utility class for obtaining Rev object instances.
- */
-public class RevUtils {
-
-	private RevUtils() {
-		// non instanciable utility class
-	}
-
-	/**
-	 * Finds and returns instance of common ancestor commit for given to
-	 * commit's
-	 *
-	 * @param repo repository in which common ancestor should be searched, cannot be null
-	 * @param commit1 left commit id, cannot be null
-	 * @param commit2 right commit id, cannot be null
-	 * @return common ancestor for commit1 and commit2 parameters
-	 * @throws IOException
-	 */
-	public static RevCommit getCommonAncestor(Repository repo,
-			AnyObjectId commit1, AnyObjectId commit2) throws IOException {
-		Assert.isNotNull(repo);
-		Assert.isNotNull(commit1);
-		Assert.isNotNull(commit2);
-
-		RevWalk rw = new RevWalk(repo);
-		try {
-			rw.setRetainBody(false);
-			rw.setRevFilter(RevFilter.MERGE_BASE);
-
-			RevCommit srcRev = rw.lookupCommit(commit1);
-			RevCommit dstRev = rw.lookupCommit(commit2);
-
-			rw.markStart(dstRev);
-			rw.markStart(srcRev);
-
-			RevCommit result = rw.next();
-			if (result != null) {
-				rw.parseBody(result);
-				return result;
-			} else {
-				return null;
-			}
-		} finally {
-			rw.release();
-		}
-	}
-
-	/**
-	 * Check if commit is contained in any of the passed refs.
-	 *
-	 * @param repo
-	 *            the repo the commit is in
-	 * @param commitId
-	 *            the commit ID to search for
-	 * @param refs
-	 *            the refs to check
-	 * @return true if the commit is contained, false otherwise
-	 * @throws IOException
-	 */
-	public static boolean isContainedInAnyRef(Repository repo,
-			ObjectId commitId, Collection<Ref> refs) throws IOException {
-		// It's likely that we don't have to walk commits at all, so
-		// check refs directly first.
-		for (Ref ref : refs)
-			if (commitId.equals(ref.getObjectId()))
-				return true;
-
-		RevWalk walk = new RevWalk(repo);
-		try {
-			RevCommit commit = walk.parseCommit(commitId);
-			for (Ref ref : refs) {
-				RevCommit refCommit = walk.parseCommit(ref.getObjectId());
-				boolean contained = walk.isMergedInto(commit, refCommit);
-				if (contained)
-					return true;
-			}
-		} finally {
-			walk.dispose();
-		}
-		return false;
-	}
-
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/coretext.properties b/org.eclipse.egit.core/src/org/eclipse/egit/core/coretext.properties
deleted file mode 100644
index 19d3d94..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/coretext.properties
+++ /dev/null
@@ -1,176 +0,0 @@
-###############################################################################
-# Copyright (c) 2006, 2012 Shawn Pearce and others.
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Eclipse Public License v1.0
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/epl-v10.html
-#
-# Contributors:
-#    Shawn Pearce - initial implementation
-#    Daniel Megert <daniel_megert@ch.ibm.com> - Escaped single quotes where needed
-###############################################################################
-
-CherryPickOperation_cherryPicking=Running cherry-pick on commit {0}
-CommitFileRevision_pathNotIn=Path {1} not in commit {0}.
-CommitFileRevision_errorLookingUpPath=IO error looking up path {1} in {0}.
-ConfigureFetchAfterCloneTask_couldNotFetch=Could not fetch with refSpec {0}
-ConnectProviderOperation_connecting=Connecting Git team provider.
-ConnectProviderOperation_ConnectingProject=Connecting project {0}
-
-DeleteBranchOperation_TaskName=Deleting branch {0}
-DeleteTagOperation_exceptionMessage=Exception deleting tag ''{0}''
-DiffHeaderFormat_Email=email
-DiffHeaderFormat_None=None
-DiffHeaderFormat_Oneline=oneline
-DiffHeaderFormat_Workspace=Workspace
-DiscardChangesOperation_discardFailed=Discarding changes of {0} failed
-DiscardChangesOperation_discardFailedSeeLog=Discarding changes failed. See log for details
-DiscardChangesOperation_discardingChanges=Discarding changes
-DiscardChangesOperation_refreshFailed=Refreshing resources failed
-DeleteResourcesOperation_deletingResources=Deleting resources
-DeleteResourcesOperation_deleteFailed=Deleting resource {0} failed.
-DeleteResourcesOperation_deleteFailedSeeLog=Deleting resources failed. See log for details
-DisconnectProviderOperation_disconnecting=Disconnecting Git team provider.
-
-Activator_autoIgnoreDerivedResources=Auto-ignore derived resources
-Activator_AutoShareJobName=Auto share git projects
-Activator_AutoSharingFailed=Auto sharing project with git failed
-Activator_ignoreResourceFailed=Ignoring {0} failed
-Activator_ReconfigureWindowCacheError=Exception when reconfiguring window cache from configuration, default configuration will be used
-
-AssumeUnchangedOperation_adding=Marking resources unchanged
-AssumeUnchangedOperation_writingIndex=Writing index for {0}
-BlobStorage_blobNotFound=Git blob {0} with path {1} not found
-BlobStorage_errorReadingBlob=IO error reading Git blob {0} with path {1}
-
-CommitOperation_errorCommittingChanges=Committing changes
-CommitOperation_errorPreparingTrees=Preparing trees
-CommitOperation_errorWritingTrees=Writing trees
-CommitOperation_failedToUpdate=Failed to update {0} to commit {1}.
-CommitOperation_PerformingCommit=Performing commit
-CommitOperation_couldNotFindRepositoryMapping=Could not find RepositoryMapping for {0}
-CommitOperation_errorParsingPersonIdent=The person ident ''{0}'' could not be parsed.
-
-UntrackOperation_adding=Untracking (removing) resources.
-UntrackOperation_failed=Failed to untrack resource.
-UntrackOperation_writingIndex=Writing index for {0}
-
-GitFileHistory_errorParsingHistory=Error parsing history for {0}.
-GitFileHistory_gitNotAttached=Git not attached to project {0}.
-GitFileHistory_invalidHeadRevision=Invalid HEAD revision for project {0}.
-GitFileHistory_noHeadRevisionAvailable=No HEAD revision available from Git for project {0}.
-GitProjectData_mappedResourceGone=Git mapped resource no longer exists in Eclipse: ''{0}''
-GitProjectData_failedFindingRepoMapping=Failed finding RepositoryMapping
-GitProjectData_failedToCacheRepoMapping=Failed to cache RepositoryMapping
-GitProjectData_FailedToMarkTeamPrivate=Failed to mark {0} as team private
-GitProjectData_missing=Git team provider configuration has gone missing.
-GitProjectData_saveFailed=Saving Git team provider data to {0} failed.
-
-RepositoryFinder_finding=Searching for associated repositories.
-RepositoryUtil_noHead=NO-HEAD
-ResetOperation_cantUpdate=Can''t update {0}
-ResetOperation_lookingUpCommit=looking up commit {0}
-ResetOperation_lookingUpRef=looking up ref {0}
-ResetOperation_mappingTreeForCommit=mapping tree for commit
-ResetOperation_performingReset=Performing {0} reset to {1}
-ResetOperation_readingIndex=Reading index
-ResetOperation_resetMergeFailed=Resetting merge mode failed
-ResetOperation_resetCherryPickFailed=Resetting cherry pick mode failed
-ResetOperation_updatingFailed=Updating {0} failed
-
-MergeOperation_CheckoutConflict=Checkout conflict: Your local changes to {0}\nwould be overwritten by merge.  Aborting. Commit your changes or stash them before you can merge.
-MergeOperation_InternalError=An internal error occurred
-MergeOperation_MergeFailedNoHead=Merge failed: Reference to HEAD does not exist
-MergeOperation_MergeFailedRefUpdate=Merge failed: Another process is accessing the ref
-MergeOperation_ProgressMerge=Merge {0}
-MoveDeleteHook_cannotModifyFolder=Folder contains an active Git repository.\n\
-The folder cannot be moved, renamed or deleted until the team provider is disconnected.
-
-MoveDeleteHook_operationError=Error updating cache during move/delete.\n\
-The resource cannot be moved, renamed or deleted due to an internal error.
-MoveDeleteHook_unmergedFileError=Move of file was canceled because it has conflicts.\n\
-Resolve the conflicts first and then move the file.
-MoveDeleteHook_unmergedFileInFolderError=Move of folder was canceled because it contains files with conflicts.\n\
-Resolve the conflicts first and then move the folder.
-
-Error_CanonicalFile=Unable to determine a canonical file path.
-
-ProjectReference_InvalidTokensCount={0} tokens expected in project reference but {1} had been found: {2}
-GitProjectSetCapability_CloneToExistingDirectory=Destination directory {0} already exists and doesn''t contain the expected Git repository. Won''t clone {1} from {2} to prevent data loss.
-GitProjectSetCapability_ExportCouldNotGetBranch=Could not get current branch from repository of project {0}.
-GitProjectSetCapability_ExportNoRemote=No remote URL configured for current branch in repository of project {0}.
-
-CloneOperation_checkingOutFiles=Checking out files
-CloneOperation_failed_cleanup=Clone operation failed, with failed cleanup: {0}. Manual cleanup may be required.
-CloneOperation_initializingRepository=Initializing local repository
-CloneOperation_title=Cloning from {0}
-CloneOperation_writingIndex=Writing index
-CreateLocalBranchOperation_CreatingBranchMessage=Creating branch {0}
-CreatePatchOperation_repoRequired=A repository is required  to create a patch
-CreatePatchOperation_cannotCreatePatchForMergeCommit=Cannot create patch for merge commit
-CreatePatchOperation_cannotCreatePatchForFirstCommit=Cannot create patch for first commit
-CreatePatchOperation_couldNotFindProject=Could not find project for {0} in repository {1}
-CreatePatchOperation_patchFileCouldNotBeWritten=Patch file could not be written
-IndexDiffCacheEntry_errorCalculatingIndexDelta=Failed to load index for repository {0}
-IndexDiffCacheEntry_refreshingProjects=Refreshing projects of repository {0}
-IndexDiffCacheEntry_reindexing=Re-indexing repository {0}
-IndexFileRevision_errorLookingUpPath=IO error looking up path {0} in index.
-IndexFileRevision_indexEntryNotFound=Git index entry for path {1} not found
-
-ListRemoteOperation_title=Getting remote branches information
-
-ProjectUtil_refreshingProjects=Refreshing projects
-ProjectUtil_refreshing=Refreshing
-ProjectUtil_taskCheckingDirectory=Checking: {0}
-PullOperation_DetachedHeadMessage=No local branch is currently checked out
-PullOperation_PullNotConfiguredMessage=The current branch is not configured for pull
-PullOperation_TaskName=Pulling {0} repositories
-PushOperation_InternalExceptionOccurredMessage=An internal Exception occurred during push: {0}
-PushOperation_ExceptionOccurredDuringPushOnUriMessage=An exception occurred during push on URI {0}: {1}
-PushOperation_resultCancelled=Operation was cancelled.
-PushOperation_taskNameDryRun=Trying pushing to remote repositories
-PushOperation_taskNameNormalRun=Pushing to remote repositories
-
-AddToIndexOperation_failed=Failed to add resource to index
-RemoveFromIndexOperation_removingFilesFromIndex=Removing files from index
-RemoveFromIndexOperation_failed=Failed to remove resource from index
-
-BranchOperation_closingMissingProject=Closing project ''{0}''
-BranchOperation_performingBranch=Switching to {0}
-TagOperation_performingTagging=Making tag {0}
-TagOperation_taggingFailure=Tag {0} creation failed (cause: {1})
-TagOperation_objectIdNotFound=Could not find object Id associated with tag {0} (cause: {1})
-
-GitFolderResourceVariant_fetchingMembers=Fetching members of {0}
-
-GitResourceVariantTree_couldNotFindResourceVariant=Could not find variant for resource: {0}
-GitResourceVariantTree_couldNotFetchMembers=Could not fetch members of {0}
-GitResourceVariantTree_fetchingVariant=Fetching variant for: {0}
-
-GitBranchResourceVariantTreeSubscriber_gitRepository=Git without local changes
-OperationAlreadyExecuted=Operation has already been executed and can not be executed again
-OperationNotYetExecuted=Operation has not yet been executed and can not return a result
-RemoteRefUpdateCantBeReused=The RemoteRefUpdate instance can not be re-used
-RenameBranchOperation_TaskName=Renaming branch {0} to {1}
-RevertCommitOperation_reverting=Reverting commit {0}
-
-IgnoreOperation_error=Unable to ignore resources
-IgnoreOperation_parentOutsideRepo=Can not add to gitignore. The parent of {0} is outside the Git repository {1}
-IgnoreOperation_creatingFailed=creating {0} failed
-IgnoreOperation_taskName=Adding resources to gitignore
-IgnoreOperation_updatingFailed=updating {0} failed
-
-GitSubscriberMergeContext_FailedUpdateRevs=Failed to update revisions
-GitSubscriberMergeContext_FailedRefreshSyncView=Failed to refresh synchronize view
-
-GitProjectData_repositoryChangedJobName=Git repository changed job
-GitProjectData_repositoryChangedTaskName=Git repository changed
-
-GitResourceVariantTreeSubscriber_fetchTaskName=Fetching data from git repositories
-
-GitSyncObjectCache_noData=Cache doesn''t contain data for key: {0}
-
-GitRemoteFolder_fetchingMembers=Fetching members of {0}
-
-GitURI_InvalidSCMURL=Invalid SCM URL {0}
-GitURI_InvalidURI=Invalid uri {0}: {1}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/Activator.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/Activator.java
new file mode 100644
index 0000000..53d3d66
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/Activator.java
@@ -0,0 +1,383 @@
+/*******************************************************************************
+ * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
+ * Copyright (C) 2011, 2013 Matthias Sohn <matthias.sohn@sap.com>
+ * Copyright (C) 2013, Robin Stocker <robin@nibor.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal;
+
+import java.io.File;
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.List;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IResourceDeltaVisitor;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Plugin;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.preferences.DefaultScope;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.egit.core.internal.indexdiff.IndexDiffCache;
+import org.eclipse.egit.core.internal.job.JobUtil;
+import org.eclipse.egit.core.internal.op.ConnectProviderOperation;
+import org.eclipse.egit.core.internal.op.IgnoreOperation;
+import org.eclipse.egit.core.internal.project.GitProjectData;
+import org.eclipse.egit.core.internal.project.RepositoryFinder;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.egit.core.internal.securestorage.EGitSecureStore;
+import org.eclipse.egit.core.internal.trace.GitTraceLocation;
+import org.eclipse.equinox.security.storage.SecurePreferencesFactory;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.util.FS;
+import org.eclipse.osgi.service.debug.DebugOptions;
+import org.eclipse.osgi.service.debug.DebugOptionsListener;
+import org.eclipse.team.core.RepositoryProvider;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The plugin class for the org.eclipse.egit.core plugin. This
+ * is a singleton class.
+ */
+public class Activator extends Plugin implements DebugOptionsListener {
+	private static Activator plugin;
+	private static String pluginId;
+	private RepositoryCache repositoryCache;
+	private IndexDiffCache indexDiffCache;
+	private RepositoryUtil repositoryUtil;
+	private EGitSecureStore secureStore;
+	private AutoShareProjects shareGitProjectsJob;
+	private IResourceChangeListener preDeleteProjectListener;
+	private IgnoreDerivedResources ignoreDerivedResourcesListener;
+
+	/**
+	 * @return the singleton {@link Activator}
+	 */
+	public static Activator getDefault() {
+		return plugin;
+	}
+
+	/**
+	 * @return the name of this plugin
+	 */
+	public static String getPluginId() {
+		return pluginId;
+	}
+
+	/**
+	 * Utility to create an error status for this plug-in.
+	 *
+	 * @param message User comprehensible message
+	 * @param thr cause
+	 * @return an initialized error status
+	 */
+	public static IStatus error(final String message, final Throwable thr) {
+		return new Status(IStatus.ERROR, getPluginId(), 0,	message, thr);
+	}
+
+	/**
+	 * Utility method to log errors in the Egit plugin.
+	 * @param message User comprehensible message
+	 * @param thr The exception through which we noticed the error
+	 */
+	public static void logError(final String message, final Throwable thr) {
+		getDefault().getLog().log(
+				new Status(IStatus.ERROR, getPluginId(), 0, message, thr));
+	}
+
+	/**
+	 * Construct the {@link Activator} singleton instance
+	 */
+	public Activator() {
+		Activator.setActivator(this);
+	}
+
+	private static void setActivator(Activator a) {
+		plugin = a;
+	}
+
+	public void start(final BundleContext context) throws Exception {
+
+		super.start(context);
+
+		pluginId = context.getBundle().getSymbolicName();
+
+		// we want to be notified about debug options changes
+		Dictionary<String, String> props = new Hashtable<String, String>(4);
+		props.put(DebugOptions.LISTENER_SYMBOLICNAME, pluginId);
+		context.registerService(DebugOptionsListener.class.getName(), this,
+				props);
+
+		repositoryCache = new RepositoryCache();
+		indexDiffCache = new IndexDiffCache();
+		try {
+			GitProjectData.reconfigureWindowCache();
+		} catch (RuntimeException e) {
+			logError(CoreText.Activator_ReconfigureWindowCacheError, e);
+		}
+		GitProjectData.attachToWorkspace(true);
+
+		IEclipsePreferences node = InstanceScope.INSTANCE.getNode(Activator.getPluginId());
+		String gitPrefix = node.get(GitCorePreferences.core_gitPrefix, null);
+		if (gitPrefix != null)
+			FS.DETECTED.setGitPrefix(new File(gitPrefix));
+
+		repositoryUtil = new RepositoryUtil();
+
+		secureStore = new EGitSecureStore(SecurePreferencesFactory.getDefault());
+
+		registerAutoShareProjects();
+		registerAutoIgnoreDerivedResources();
+		registerPreDeleteResourceChangeListener();
+	}
+
+	private void registerPreDeleteResourceChangeListener() {
+		if (preDeleteProjectListener == null) {
+			preDeleteProjectListener = new IResourceChangeListener() {
+
+				public void resourceChanged(IResourceChangeEvent event) {
+					IResource resource = event.getResource();
+					if (resource instanceof IProject) {
+						IProject project = (IProject) resource;
+						if (RepositoryProvider.getProvider(project) instanceof GitProvider) {
+							IResource dotGit = project.findMember(Constants.DOT_GIT);
+							if (dotGit != null && dotGit.getType() == IResource.FOLDER)
+								GitProjectData.reconfigureWindowCache();
+						}
+					}
+				}
+			};
+			ResourcesPlugin.getWorkspace().addResourceChangeListener(preDeleteProjectListener, IResourceChangeEvent.PRE_DELETE);
+		}
+	}
+
+	public void optionsChanged(DebugOptions options) {
+		// initialize the trace stuff
+		GitTraceLocation.initializeFromOptions(options, isDebugging());
+	}
+
+	/**
+	 *  @return cache for Repository objects
+	 */
+	public RepositoryCache getRepositoryCache() {
+		return repositoryCache;
+	}
+
+	/**
+	 *  @return cache for index diffs
+	 */
+	public IndexDiffCache getIndexDiffCache() {
+		return indexDiffCache;
+	}
+
+	/**
+	 * @return the {@link RepositoryUtil} instance
+	 */
+	public RepositoryUtil getRepositoryUtil() {
+		return repositoryUtil;
+	}
+
+	/**
+	 * @return the secure store
+	 */
+	public EGitSecureStore getSecureStore() {
+		return secureStore;
+	}
+
+	public void stop(final BundleContext context) throws Exception {
+		GitProjectData.detachFromWorkspace();
+		repositoryCache = null;
+		indexDiffCache.dispose();
+		indexDiffCache = null;
+		repositoryUtil.dispose();
+		repositoryUtil = null;
+		secureStore = null;
+		super.stop(context);
+		plugin = null;
+		if (preDeleteProjectListener != null) {
+			ResourcesPlugin.getWorkspace().removeResourceChangeListener(preDeleteProjectListener);
+			preDeleteProjectListener = null;
+		}
+		if (ignoreDerivedResourcesListener != null) {
+			ResourcesPlugin.getWorkspace().removeResourceChangeListener(
+					ignoreDerivedResourcesListener);
+			ignoreDerivedResourcesListener = null;
+		}
+		if (shareGitProjectsJob != null) {
+			ResourcesPlugin.getWorkspace().removeResourceChangeListener(
+					shareGitProjectsJob);
+			shareGitProjectsJob = null;
+		}
+	}
+
+	private void registerAutoShareProjects() {
+		shareGitProjectsJob = new AutoShareProjects();
+		ResourcesPlugin.getWorkspace().addResourceChangeListener(
+				shareGitProjectsJob, IResourceChangeEvent.POST_CHANGE);
+	}
+
+	private static class AutoShareProjects implements
+			IResourceChangeListener {
+
+		private static int INTERESTING_CHANGES = IResourceDelta.ADDED
+				| IResourceDelta.OPEN;
+
+		public AutoShareProjects() {
+			// empty
+		}
+
+		private boolean doAutoShare() {
+			IEclipsePreferences d = DefaultScope.INSTANCE.getNode(Activator
+					.getPluginId());
+			IEclipsePreferences p = InstanceScope.INSTANCE.getNode(Activator
+					.getPluginId());
+			return p.getBoolean(GitCorePreferences.core_autoShareProjects, d
+					.getBoolean(GitCorePreferences.core_autoShareProjects,
+							true));
+		}
+
+		public void resourceChanged(IResourceChangeEvent event) {
+			try {
+				event.getDelta().accept(new IResourceDeltaVisitor() {
+
+					public boolean visit(IResourceDelta delta)
+							throws CoreException {
+						if (!doAutoShare())
+							return false;
+						if (delta.getKind() == IResourceDelta.CHANGED
+								&& (delta.getFlags() & INTERESTING_CHANGES) == 0)
+							return true;
+						final IResource resource = delta.getResource();
+						if (!resource.exists() || !resource.isAccessible() ||
+								resource.isLinked(IResource.CHECK_ANCESTORS))
+							return false;
+						if (resource.getType() != IResource.PROJECT)
+							return true;
+						if (RepositoryMapping.getMapping(resource) != null)
+							return false;
+						final IProject project = (IProject) resource;
+						RepositoryProvider provider = RepositoryProvider
+								.getProvider(project);
+						// respect if project is already shared with another
+						// team provider
+						if (provider != null)
+							return false;
+						RepositoryFinder f = new RepositoryFinder(project);
+						Collection<RepositoryMapping> mappings = f.find(new NullProgressMonitor());
+						try {
+							if (mappings.size() == 1) {
+								// connect
+								RepositoryMapping m = mappings.iterator()
+										.next();
+								final File repositoryDir = m
+										.getGitDirAbsolutePath().toFile();
+								final ConnectProviderOperation op = new ConnectProviderOperation(
+										project, repositoryDir);
+								JobUtil.scheduleUserJob(op,
+										CoreText.Activator_AutoShareJobName,
+										JobFamilies.AUTO_SHARE);
+								Activator.getDefault().getRepositoryUtil()
+										.addConfiguredRepository(repositoryDir);
+							}
+						} catch (IllegalArgumentException e) {
+							logError(CoreText.Activator_AutoSharingFailed, e);
+						}
+						return false;
+					}
+				});
+			} catch (CoreException e) {
+				Activator.logError(e.getMessage(), e);
+				return;
+			}
+		}
+	}
+
+	private void registerAutoIgnoreDerivedResources() {
+		ignoreDerivedResourcesListener = new IgnoreDerivedResources();
+		ResourcesPlugin.getWorkspace().addResourceChangeListener(
+				ignoreDerivedResourcesListener,
+				IResourceChangeEvent.POST_CHANGE);
+	}
+
+	private static class IgnoreDerivedResources implements
+			IResourceChangeListener {
+
+		protected boolean autoIgnoreDerived() {
+			IEclipsePreferences d = DefaultScope.INSTANCE.getNode(Activator
+					.getPluginId());
+			IEclipsePreferences p = InstanceScope.INSTANCE.getNode(Activator
+					.getPluginId());
+			return p.getBoolean(
+					GitCorePreferences.core_autoIgnoreDerivedResources,
+					d.getBoolean(
+							GitCorePreferences.core_autoIgnoreDerivedResources,
+							true));
+		}
+
+		public void resourceChanged(IResourceChangeEvent event) {
+			try {
+				IResourceDelta d = event.getDelta();
+				if (d == null || !autoIgnoreDerived())
+					return;
+
+				final List<IPath> toBeIgnored = new ArrayList<IPath>();
+
+				d.accept(new IResourceDeltaVisitor() {
+
+					public boolean visit(IResourceDelta delta)
+							throws CoreException {
+						if ((delta.getKind() & (IResourceDelta.ADDED | IResourceDelta.CHANGED)) == 0)
+							return false;
+						int flags = delta.getFlags();
+						if ((flags != 0)
+								&& ((flags & IResourceDelta.DERIVED_CHANGED) == 0))
+							return false;
+
+						final IResource r = delta.getResource();
+						if (r.isTeamPrivateMember())
+							return false;
+
+						if (r.isDerived()) {
+							try {
+								if (!RepositoryUtil.isIgnored(r.getLocation()))
+									toBeIgnored.add(r.getLocation());
+							} catch (IOException e) {
+								logError(
+										MessageFormat.format(
+												CoreText.Activator_ignoreResourceFailed,
+												r.getFullPath()), e);
+							}
+							return false;
+						}
+						return true;
+					}
+				});
+				if (toBeIgnored.size() > 0)
+					JobUtil.scheduleUserJob(new IgnoreOperation(toBeIgnored),
+							CoreText.Activator_autoIgnoreDerivedResources,
+							JobFamilies.AUTO_IGNORE);
+			} catch (CoreException e) {
+				Activator.logError(e.getMessage(), e);
+				return;
+			}
+		}
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/AdaptableFileTreeIterator.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/AdaptableFileTreeIterator.java
new file mode 100644
index 0000000..0afb0fb
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/AdaptableFileTreeIterator.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (C) 2009, Tor Arne Vestbø <torarnv@gmail.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.egit.core.internal;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.jgit.errors.IncorrectObjectTypeException;
+import org.eclipse.jgit.lib.ObjectReader;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.treewalk.AbstractTreeIterator;
+import org.eclipse.jgit.treewalk.FileTreeIterator;
+import org.eclipse.jgit.treewalk.WorkingTreeIterator;
+import org.eclipse.jgit.util.FS;
+
+/**
+ * Java IO file tree iterator that can adapt to a {@link ContainerTreeIterator}
+ * <p>
+ * The iterator automatically adapts to a {@link ContainerTreeIterator} when
+ * recursing into directories that are accessible from the given workspace root.
+ *
+ * @see org.eclipse.jgit.treewalk.FileTreeIterator
+ * @see org.eclipse.egit.core.internal.ContainerTreeIterator
+ */
+public class AdaptableFileTreeIterator extends FileTreeIterator {
+
+	IWorkspaceRoot root;
+
+	/**
+	 * Create a new iterator to traverse the work tree of the given repository
+	 * <p>
+	 * The iterator will automatically adapt to a {@link ContainerTreeIterator}
+	 * when encountering directories what can be mapped into the given workspace
+	 * root.
+	 *
+	 * @param repository
+	 *            the repository this iterator should traverse the working tree
+	 *            of
+	 * @param workspaceRoot
+	 *            the workspace root to check resource mapping against.
+	 */
+	public AdaptableFileTreeIterator(final Repository repository,
+			final IWorkspaceRoot workspaceRoot) {
+		super(repository);
+		root = workspaceRoot;
+	}
+
+	/**
+	 * Create a new iterator to traverse a subdirectory.
+	 * <p>
+	 * The iterator will automatically adapt to a {@link ContainerTreeIterator}
+	 * when encountering directories what can be mapped into the given workspace
+	 * root.
+	 *
+	 * @param path
+	 *            the subdirectory. This should be a directory contained within
+	 *            the parent directory.
+	 * @param parent
+	 *            the parent iterator we were created from.
+	 * @param workspaceRoot
+	 *            the workspace root to check resource mapping against.
+	 */
+	protected AdaptableFileTreeIterator(final WorkingTreeIterator parent,
+			File path, final IWorkspaceRoot workspaceRoot) {
+		super(parent, path, FS.DETECTED);
+		root = workspaceRoot;
+	}
+
+	@Override
+	public AbstractTreeIterator createSubtreeIterator(ObjectReader repo)
+			throws IncorrectObjectTypeException, IOException {
+		final File currentFile = ((FileEntry) current()).getFile();
+		IContainer container = IteratorService.findContainer(root, currentFile);
+		if (container != null)
+			return new ContainerTreeIterator(this, container);
+		return new AdaptableFileTreeIterator(this, currentFile, root);
+	}
+
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/AdapterUtils.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/AdapterUtils.java
new file mode 100644
index 0000000..f2088ab
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/AdapterUtils.java
@@ -0,0 +1,42 @@
+/******************************************************************************
+ *  Copyright (c) 2011 GitHub Inc.
+ *  All rights reserved. This program and the accompanying materials
+ *  are made available under the terms of the Eclipse Public License v1.0
+ *  which accompanies this distribution, and is available at
+ *  http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *    Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *****************************************************************************/
+package org.eclipse.egit.core.internal;
+
+import org.eclipse.core.runtime.IAdaptable;
+
+/**
+ * Utilities for working with objects that implement {@link IAdaptable}
+ */
+public class AdapterUtils {
+
+	private AdapterUtils() {
+		// Cannot be instantiated
+	}
+
+	/**
+	 * Adapt object to given target class type
+	 *
+	 * @param object
+	 * @param target
+	 * @param <V> type of target
+	 * @return adapted
+	 */
+	@SuppressWarnings("unchecked")
+	public static <V> V adapt(Object object, Class<V> target) {
+		if (object == null)
+			return null;
+		if (target.isInstance(object))
+			return (V) object;
+		if (object instanceof IAdaptable)
+			return (V) ((IAdaptable) object).getAdapter(target);
+		return null;
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/ContainerTreeIterator.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/ContainerTreeIterator.java
new file mode 100644
index 0000000..2a4be4a
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/ContainerTreeIterator.java
@@ -0,0 +1,375 @@
+/*******************************************************************************
+ * Copyright (C) 2008, 2012 Google Inc. and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.egit.core.internal;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceFilterDescription;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.jgit.errors.IncorrectObjectTypeException;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.FileMode;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.ObjectReader;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.treewalk.AbstractTreeIterator;
+import org.eclipse.jgit.treewalk.FileTreeIterator.FileEntry;
+import org.eclipse.jgit.treewalk.WorkingTreeIterator;
+import org.eclipse.jgit.treewalk.WorkingTreeOptions;
+import org.eclipse.jgit.util.FS;
+
+/**
+ * Adapts an Eclipse {@link IContainer} for use in a <code>TreeWalk</code>.
+ * <p>
+ * This iterator converts an Eclipse IContainer object into something that a
+ * TreeWalk instance can iterate over in parallel with any other Git tree data
+ * structure, such as another working directory tree from outside of the
+ * workspace or a stored tree from a Repository object database.
+ * <p>
+ * Modification times provided by this iterator are obtained from the cache
+ * Eclipse uses to track external resource modification. This can be faster, but
+ * requires the user refresh their workspace when external modifications take
+ * place. This is not really a concern as it is common practice to need to do a
+ * workspace refresh after externally modifying a file.
+ *
+ * @see org.eclipse.jgit.treewalk.TreeWalk
+ */
+public class ContainerTreeIterator extends WorkingTreeIterator {
+
+	private static String computePrefix(final IContainer base) {
+		final RepositoryMapping rm = RepositoryMapping.getMapping(base);
+		if (rm == null)
+			throw new IllegalArgumentException(
+					"Not in a Git project: " + base);  //$NON-NLS-1$
+		return rm.getRepoRelativePath(base);
+	}
+
+	private final IContainer node;
+
+	/**
+	 * Construct a new iterator from a container in the workspace.
+	 * <p>
+	 * The iterator will support traversal over the named container, but only if
+	 * it is contained within a project which has the Git repository provider
+	 * connected and this resource is mapped into a Git repository. During the
+	 * iteration the paths will be automatically generated to match the proper
+	 * repository paths for this container's children.
+	 *
+	 * @param repository
+	 *            repository the given base is mapped to
+	 * @param base
+	 *            the part of the workspace the iterator will walk over.
+	 */
+	public ContainerTreeIterator(final Repository repository, final IContainer base) {
+		super(computePrefix(base), repository.getConfig().get(WorkingTreeOptions.KEY));
+		node = base;
+		init(entries(false));
+		initRootIterator(repository);
+	}
+
+	/**
+	 * Construct a new iterator from the workspace root.
+	 * <p>
+	 * The iterator will support traversal over workspace projects that have
+	 * a Git repository provider connected and is mapped into a Git repository.
+	 * During the iteration the paths will be automatically generated to match
+	 * the proper repository paths for this container's children.
+	 *
+	 * @param repository
+	 *            repository the given base is mapped to
+	 * @param root
+	 *            the workspace root to walk over.
+	 */
+	public ContainerTreeIterator(final Repository repository, final IWorkspaceRoot root) {
+		super("", repository.getConfig().get(WorkingTreeOptions.KEY));  //$NON-NLS-1$
+		node = root;
+		init(entries(false));
+		initRootIterator(repository);
+	}
+
+	/**
+	 * Construct a new iterator from a container in the workspace, with a given
+	 * parent iterator.
+	 * <p>
+	 * The iterator will support traversal over the named container, but only if
+	 * it is contained within a project which has the Git repository provider
+	 * connected and this resource is mapped into a Git repository. During the
+	 * iteration the paths will be automatically generated to match the proper
+	 * repository paths for this container's children.
+	 *
+	 * @param p
+	 *            the parent iterator we were created from.
+	 * @param base
+	 *            the part of the workspace the iterator will walk over.
+	 */
+	public ContainerTreeIterator(final WorkingTreeIterator p,
+			final IContainer base) {
+		this(p, base, false);
+	}
+
+	private ContainerTreeIterator(final WorkingTreeIterator p,
+			final IContainer base, final boolean hasInheritedResourceFilters) {
+		super(p);
+		node = base;
+		init(entries(hasInheritedResourceFilters));
+	}
+
+	@Override
+	public AbstractTreeIterator createSubtreeIterator(ObjectReader reader)
+			throws IncorrectObjectTypeException, IOException {
+		if (FileMode.TREE.equals(mode)) {
+			if (current() instanceof ResourceEntry) {
+				ResourceEntry resourceEntry = (ResourceEntry) current();
+				return new ContainerTreeIterator(this,
+						(IContainer) resourceEntry.rsrc,
+						resourceEntry.hasInheritedResourceFilters);
+			} else if (current() instanceof FileEntry) {
+				FileEntry fileEntry = (FileEntry) current();
+				IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+				return new AdaptableFileTreeIterator(this, fileEntry.getFile(), root);
+			} else {
+				throw new IllegalStateException("Unknown entry type: " + current()); //$NON-NLS-1$
+			}
+		} else
+			throw new IncorrectObjectTypeException(ObjectId.zeroId(),
+					Constants.TYPE_TREE);
+	}
+
+	/**
+	 * Get the ResourceEntry for the current entry.
+	 *
+	 * @return the current entry
+	 */
+	public ResourceEntry getResourceEntry() {
+		return (ResourceEntry) current();
+	}
+
+	private Entry[] entries(final boolean hasInheritedResourceFilters) {
+		final IResource[] resources;
+		try {
+			resources = node.members(IContainer.INCLUDE_HIDDEN);
+		} catch (CoreException err) {
+			return EOF;
+		}
+
+		List<Entry> entries = new ArrayList<Entry>(resources.length);
+
+		boolean inheritableResourceFilter = addFilteredEntries(
+				hasInheritedResourceFilters, resources, entries);
+
+		for (IResource resource : resources)
+			if (!resource.isLinked())
+				entries.add(new ResourceEntry(resource, inheritableResourceFilter));
+
+		return entries.toArray(new Entry[entries.size()]);
+	}
+
+	/**
+	 * Add entries for filtered resources.
+	 *
+	 * @param hasInheritedResourceFilters
+	 *            true if resource filters of parents could be active, false
+	 *            otherwise
+	 * @param memberResources
+	 *            the resources returned from members() that do not have to be
+	 *            added as entries again
+	 * @param entries
+	 *            where entries should be added to
+	 * @return true if we now have resource filters that are inherited, false if
+	 *         there are no resource filters which are inherited.
+	 */
+	private boolean addFilteredEntries(
+			final boolean hasInheritedResourceFilters,
+			final IResource[] memberResources, final List<Entry> entries) {
+		// Inheritable resource filters must be propagated.
+		boolean inheritableResourceFilter = hasInheritedResourceFilters;
+		IResourceFilterDescription[] filters;
+		try {
+			filters = node.getFilters();
+		} catch (CoreException e) {
+			// Should not happen, but assume we have no filters then.
+			filters = new IResourceFilterDescription[] {};
+		}
+
+		if (filters.length != 0 || hasInheritedResourceFilters) {
+			if (!inheritableResourceFilter) {
+				for (IResourceFilterDescription filter : filters) {
+					boolean inheritable = (filter.getType() & IResourceFilterDescription.INHERITABLE) != 0;
+					if (inheritable)
+						inheritableResourceFilter = true;
+				}
+			}
+
+			Set<File> resourceEntries = new HashSet<File>();
+			for (IResource resource : memberResources)
+				// Make sure linked resources are ignored here.
+				// This is particularly important in the case of a linked
+				// resource which targets a normally filtered/hidden file
+				// within the same location. In such case, ignoring it here
+				// ensures the actual target gets included in the code below.
+				if (!resource.isLinked()) {
+					IPath location = resource.getLocation();
+					if (location != null)
+						resourceEntries.add(location.toFile());
+				}
+
+			IPath containerLocation = node.getLocation();
+			if (containerLocation != null) {
+				File folder = containerLocation.toFile();
+				File[] children = folder.listFiles();
+				for (File child : children) {
+					if (resourceEntries.contains(child))
+						continue; // ok if linked resources are ignored earlier on
+					IPath childLocation = new Path(child.getAbsolutePath());
+					IWorkspaceRoot root = node.getWorkspace().getRoot();
+					IContainer container = root.getContainerForLocation(childLocation);
+					// Check if the container is accessible in the workspace.
+					// This may seem strange, as it was not returned from
+					// members() above, but it's the case for nested projects
+					// that are filtered directly.
+					if (container != null && container.isAccessible())
+						// Resource filters does not cross the non-member line
+						// -> stop inheriting resource filter here (false)
+						entries.add(new ResourceEntry(container, false));
+					else
+						entries.add(new FileEntry(child, FS.DETECTED));
+				}
+			}
+		}
+		return inheritableResourceFilter;
+	}
+
+	/**
+	 * Wrapper for a resource in the Eclipse workspace
+	 */
+	static public class ResourceEntry extends Entry {
+		final IResource rsrc;
+		final boolean hasInheritedResourceFilters;
+
+		private final FileMode mode;
+
+		private long length = -1;
+
+		ResourceEntry(final IResource f, final boolean hasInheritedResourceFilters) {
+			rsrc = f;
+			this.hasInheritedResourceFilters = hasInheritedResourceFilters;
+
+			switch (f.getType()) {
+			case IResource.FILE:
+				File file = asFile();
+				if (FS.DETECTED.supportsExecute() && file != null
+						&& FS.DETECTED.canExecute(file))
+					mode = FileMode.EXECUTABLE_FILE;
+				else
+					mode = FileMode.REGULAR_FILE;
+				break;
+			case IResource.PROJECT:
+			case IResource.FOLDER: {
+				final IContainer c = (IContainer) f;
+				if (c.findMember(Constants.DOT_GIT) != null)
+					mode = FileMode.GITLINK;
+				else
+					mode = FileMode.TREE;
+				break;
+			}
+			default:
+				mode = FileMode.MISSING;
+				break;
+			}
+		}
+
+		@Override
+		public FileMode getMode() {
+			return mode;
+		}
+
+		@Override
+		public String getName() {
+			if (rsrc.getType() == IResource.PROJECT)
+				return rsrc.getLocation().lastSegment();
+			else
+				return rsrc.getName();
+		}
+
+		@Override
+		public long getLength() {
+			if (length < 0)
+				if (rsrc instanceof IFile) {
+					File file = asFile();
+					if (file != null)
+						length = file.length();
+					else
+						length = 0;
+				} else
+					length = 0;
+			return length;
+		}
+
+		@Override
+		public long getLastModified() {
+			return rsrc.getLocalTimeStamp();
+		}
+
+		@Override
+		public InputStream openInputStream() throws IOException {
+			if (rsrc.getType() == IResource.FILE)
+				try {
+					return ((IFile) rsrc).getContents(true);
+				} catch (CoreException err) {
+					final IOException ioe = new IOException(err.getMessage());
+					ioe.initCause(err);
+					throw ioe;
+				}
+			throw new IOException("Not a regular file: " + rsrc);  //$NON-NLS-1$
+		}
+
+		/**
+		 * Get the underlying resource of this entry.
+		 *
+		 * @return the underlying resource
+		 */
+		public IResource getResource() {
+			return rsrc;
+		}
+
+		/**
+		 * @return file of the resource or null
+		 */
+		private File asFile() {
+			return ContainerTreeIterator.asFile(rsrc);
+		}
+	}
+
+	private static File asFile(IResource resource) {
+		final IPath location = resource.getLocation();
+		return location != null ? location.toFile() : null;
+	}
+
+	protected byte[] idSubmodule(Entry e) {
+		File nodeFile = asFile(node);
+		if (nodeFile != null)
+			return idSubmodule(nodeFile, e);
+		return super.idSubmodule(e);
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/CoreText.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/CoreText.java
new file mode 100644
index 0000000..a8b8cb7
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/CoreText.java
@@ -0,0 +1,435 @@
+/*******************************************************************************
+ * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
+ * Copyright (C) 2012, Robin Stocker <robin@nibor.org>
+ * Copyright (C) 2012, Markus Duft <markus.duft@salomon.at>
+ * Copyright (C) 2013, Matthias Sohn <matthias.sohn@sap.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Possibly Translated strings for the Egit plugin.
+ */
+public class CoreText extends NLS {
+
+	/**
+	 * Do not in-line this into the static initializer as the
+	 * "Find Broken Externalized Strings" tool will not be
+	 * able to find the corresponding bundle file.
+	 */
+	private static final String BUNDLE_NAME = "org.eclipse.egit.core.coretext"; //$NON-NLS-1$
+
+	/** */
+	public static String Activator_autoIgnoreDerivedResources;
+
+	/** */
+	public static String Activator_AutoShareJobName;
+
+	/** */
+	public static String Activator_AutoSharingFailed;
+
+	/** */
+	public static String Activator_ignoreResourceFailed;
+
+	/** */
+	public static String Activator_ReconfigureWindowCacheError;
+
+	/** */
+	public static String AssumeUnchangedOperation_adding;
+
+	/** */
+	public static String AssumeUnchangedOperation_writingIndex;
+
+	/** */
+	public static String CherryPickOperation_cherryPicking;
+
+	/** */
+	public static String CommitFileRevision_errorLookingUpPath;
+
+	/** */
+	public static String CommitFileRevision_pathNotIn;
+
+	/** */
+	public static String CommitOperation_errorCommittingChanges;
+
+	/** */
+	public static String CommitOperation_errorPreparingTrees;
+
+	/** */
+	public static String CommitOperation_errorWritingTrees;
+
+	/** */
+	public static String CommitOperation_failedToUpdate;
+
+	/** */
+	public static String CommitOperation_PerformingCommit;
+
+	/** */
+	public static String CommitOperation_couldNotFindRepositoryMapping;
+
+	/** */
+	public static String CommitOperation_errorParsingPersonIdent;
+
+	/** */
+	public static String ConfigureFetchAfterCloneTask_couldNotFetch;
+
+	/** */
+	public static String ConnectProviderOperation_connecting;
+
+	/** */
+	public static String ConnectProviderOperation_ConnectingProject;
+
+	/** */
+	public static String DeleteBranchOperation_TaskName;
+
+	/** */
+	public static String DeleteTagOperation_exceptionMessage;
+
+	/** */
+	public static String DiffHeaderFormat_Email;
+
+	/** */
+	public static String DiffHeaderFormat_None;
+
+	/** */
+	public static String DiffHeaderFormat_Oneline;
+
+	/** */
+	public static String DiffHeaderFormat_Workspace;
+
+	/** */
+	public static String DiscardChangesOperation_discardFailed;
+
+	/** */
+	public static String DiscardChangesOperation_discardFailedSeeLog;
+
+	/** */
+	public static String DiscardChangesOperation_discardingChanges;
+
+	/** */
+	public static String DiscardChangesOperation_refreshFailed;
+
+	/** */
+	public static String DeleteResourcesOperation_deletingResources;
+
+	/** */
+	public static String DeleteResourcesOperation_deleteFailed;
+
+	/** */
+	public static String DeleteResourcesOperation_deleteFailedSeeLog;
+
+	/** */
+	public static String DisconnectProviderOperation_disconnecting;
+
+	/** */
+	public static String BlobStorage_blobNotFound;
+
+	/** */
+	public static String BlobStorage_errorReadingBlob;
+
+	/** */
+	public static String UntrackOperation_adding;
+
+	/** */
+	public static String UntrackOperation_failed;
+
+	/** */
+	public static String UntrackOperation_writingIndex;
+
+	/** */
+	public static String GitFileHistory_errorParsingHistory;
+
+	/** */
+	public static String GitFileHistory_gitNotAttached;
+
+	/** */
+	public static String GitFileHistory_invalidHeadRevision;
+
+	/** */
+	public static String GitFileHistory_noHeadRevisionAvailable;
+
+	/** */
+	public static String GitProjectData_mappedResourceGone;
+
+	/** */
+	public static String GitProjectData_failedFindingRepoMapping;
+
+	/** */
+	public static String GitProjectData_failedToCacheRepoMapping;
+
+	/** */
+	public static String GitProjectData_FailedToMarkTeamPrivate;
+
+	/** */
+	public static String GitProjectData_missing;
+
+	/** */
+	public static String GitProjectData_saveFailed;
+
+	/** */
+	public static String RepositoryFinder_finding;
+
+	/** */
+	public static String RepositoryUtil_noHead;
+
+	/** */
+	public static String RemoteRefUpdateCantBeReused;
+
+	/** */
+	public static String RenameBranchOperation_TaskName;
+
+	/** */
+	public static String ResetOperation_cantUpdate;
+
+	/** */
+	public static String ResetOperation_lookingUpCommit;
+
+	/** */
+	public static String ResetOperation_lookingUpRef;
+
+	/** */
+	public static String ResetOperation_mappingTreeForCommit;
+
+	/** */
+	public static String ResetOperation_performingReset;
+
+	/** */
+	public static String ResetOperation_readingIndex;
+
+	/** */
+	public static String ResetOperation_resetMergeFailed;
+
+	/** */
+	public static String ResetOperation_resetCherryPickFailed;
+
+	/** */
+	public static String ResetOperation_updatingFailed;
+
+	/** */
+	public static String MergeOperation_CheckoutConflict;
+
+	/** */
+	public static String MergeOperation_InternalError;
+
+	/** */
+	public static String MergeOperation_MergeFailedNoHead;
+
+	/** */
+	public static String MergeOperation_MergeFailedRefUpdate;
+
+	/** */
+	public static String MergeOperation_ProgressMerge;
+
+	/** */
+	public static String MoveDeleteHook_cannotModifyFolder;
+
+	/** */
+	public static String MoveDeleteHook_operationError;
+
+	/** */
+	public static String MoveDeleteHook_unmergedFileError;
+
+	/** */
+	public static String MoveDeleteHook_unmergedFileInFolderError;
+
+	/** */
+	public static String Error_CanonicalFile;
+
+	/** */
+	public static String CloneOperation_checkingOutFiles;
+
+	/** */
+	public static String CloneOperation_failed_cleanup;
+
+	/** */
+	public static String CloneOperation_initializingRepository;
+
+	/** */
+	public static String CloneOperation_title;
+
+	/** */
+	public static String CloneOperation_writingIndex;
+
+	/** */
+	public static String CreateLocalBranchOperation_CreatingBranchMessage;
+
+	/** */
+	public static String CreatePatchOperation_repoRequired;
+
+	/** */
+	public static String CreatePatchOperation_cannotCreatePatchForMergeCommit;
+
+	/** */
+	public static String CreatePatchOperation_cannotCreatePatchForFirstCommit;
+
+	/** */
+	public static String CreatePatchOperation_couldNotFindProject;
+
+	/** */
+	public static String CreatePatchOperation_patchFileCouldNotBeWritten;
+
+	/** */
+	public static String IndexDiffCacheEntry_errorCalculatingIndexDelta;
+
+	/** */
+	public static String IndexDiffCacheEntry_refreshingProjects;
+
+	/** */
+	public static String IndexDiffCacheEntry_reindexing;
+
+	/** */
+	public static String IndexFileRevision_errorLookingUpPath;
+
+	/** */
+	public static String IndexFileRevision_indexEntryNotFound;
+
+	/** */
+	public static String ListRemoteOperation_title;
+
+	/** */
+	public static String ProjectUtil_refreshingProjects;
+
+	/** */
+	public static String ProjectUtil_refreshing;
+
+	/** */
+	public static String ProjectUtil_taskCheckingDirectory;
+
+	/** */
+	public static String PullOperation_DetachedHeadMessage;
+
+	/** */
+	public static String PullOperation_PullNotConfiguredMessage;
+
+	/** */
+	public static String PullOperation_TaskName;
+
+	/** */
+	public static String PushOperation_InternalExceptionOccurredMessage;
+
+	/** */
+	public static String PushOperation_ExceptionOccurredDuringPushOnUriMessage;
+
+	/** */
+	public static String PushOperation_resultCancelled;
+
+	/** */
+	public static String PushOperation_taskNameDryRun;
+
+	/** */
+	public static String PushOperation_taskNameNormalRun;
+
+	/** */
+	public static String AddToIndexOperation_failed;
+
+	/** */
+	public static String RemoveFromIndexOperation_removingFilesFromIndex;
+
+	/** */
+	public static String RemoveFromIndexOperation_failed;
+
+	/** */
+	public static String RevertCommitOperation_reverting;
+
+	/** */
+	public static String BranchOperation_closingMissingProject;
+
+	/** */
+	public static String BranchOperation_performingBranch;
+
+	/** */
+	public static String TagOperation_performingTagging;
+
+	/** */
+	public static String TagOperation_taggingFailure;
+
+	/** */
+	public static String TagOperation_objectIdNotFound;
+
+	/** */
+	public static String GitResourceVariantTree_couldNotFindResourceVariant;
+
+	/** */
+	public static String GitResourceVariantTree_couldNotFetchMembers;
+
+	/** */
+	public static String GitFolderResourceVariant_fetchingMembers;
+
+	/** */
+	public static String GitResourceVariantTree_fetchingVariant;
+
+	/** */
+	public static String GitBranchResourceVariantTreeSubscriber_gitRepository;
+
+	/** */
+	public static String OperationAlreadyExecuted;
+
+	/** */
+	public static String OperationNotYetExecuted;
+
+	/** */
+	public static String ProjectReference_InvalidTokensCount;
+
+	/** */
+	public static String GitProjectSetCapability_CloneToExistingDirectory;
+
+	/** */
+	public static String GitProjectSetCapability_ExportCouldNotGetBranch;
+
+	/** */
+	public static String GitProjectSetCapability_ExportNoRemote;
+
+	/** */
+	public static String IgnoreOperation_error;
+
+	/** */
+	public static String IgnoreOperation_parentOutsideRepo;
+
+	/** */
+	public static String IgnoreOperation_creatingFailed;
+
+	/** */
+	public static String IgnoreOperation_taskName;
+
+	/** */
+	public static String IgnoreOperation_updatingFailed;
+
+	/** */
+	public static String GitSubscriberMergeContext_FailedUpdateRevs;
+
+	/** */
+	public static String GitSubscriberMergeContext_FailedRefreshSyncView;
+
+	/** */
+	public static String GitProjectData_repositoryChangedJobName;
+
+	/** */
+	public static String GitProjectData_repositoryChangedTaskName;
+
+	/** */
+	public static String GitResourceVariantTreeSubscriber_fetchTaskName;
+
+	/** */
+	public static String GitSyncObjectCache_noData;
+
+	/** */
+	public static String GitRemoteFolder_fetchingMembers;
+
+	/** */
+	public static String GitURI_InvalidSCMURL;
+
+	/** */
+	public static String GitURI_InvalidURI;
+
+	static {
+		initializeMessages(BUNDLE_NAME,	CoreText.class);
+	}
+
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/EclipseGitProgressTransformer.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/EclipseGitProgressTransformer.java
new file mode 100644
index 0000000..33813e3
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/EclipseGitProgressTransformer.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.jgit.lib.ProgressMonitor;
+
+/** Create a new Git to Eclipse progress monitor. */
+public class EclipseGitProgressTransformer implements ProgressMonitor {
+	private static final String EMPTY_STRING = "";  //$NON-NLS-1$
+
+	private final IProgressMonitor root;
+
+	private IProgressMonitor task;
+
+	private String msg;
+
+	private int lastWorked;
+
+	private int totalWork;
+
+	/**
+	 * Create a new progress monitor.
+	 *
+	 * @param eclipseMonitor
+	 *            the Eclipse monitor we update.
+	 */
+	public EclipseGitProgressTransformer(final IProgressMonitor eclipseMonitor) {
+		root = eclipseMonitor;
+	}
+
+	public void start(final int totalTasks) {
+		root.beginTask(EMPTY_STRING, totalTasks * 1000);
+	}
+
+	public void beginTask(final String name, final int total) {
+		endTask();
+		msg = name;
+		lastWorked = 0;
+		totalWork = total;
+		task = new SubProgressMonitor(root, 1000);
+		if (totalWork == UNKNOWN)
+			task.beginTask(EMPTY_STRING, IProgressMonitor.UNKNOWN);
+		else
+			task.beginTask(EMPTY_STRING, totalWork);
+		task.subTask(msg);
+	}
+
+	public void update(final int work) {
+		if (task == null)
+			return;
+
+		final int cmp = lastWorked + work;
+		if (totalWork == UNKNOWN && cmp > 0) {
+			if (lastWorked != cmp)
+				task.subTask(msg + ", " + cmp); //$NON-NLS-1$
+		} else if (totalWork <= 0) {
+			// Do nothing to update the task.
+		} else if (cmp * 100 / totalWork != lastWorked * 100 / totalWork) {
+			final StringBuilder m = new StringBuilder();
+			m.append(msg);
+			m.append(": ");  //$NON-NLS-1$
+			while (m.length() < 25)
+				m.append(' ');
+
+			final String twstr = String.valueOf(totalWork);
+			String cmpstr = String.valueOf(cmp);
+			while (cmpstr.length() < twstr.length())
+				cmpstr = " " + cmpstr; //$NON-NLS-1$
+			final int pcnt = (cmp * 100 / totalWork);
+			if (pcnt < 100)
+				m.append(' ');
+			if (pcnt < 10)
+				m.append(' ');
+			m.append(pcnt);
+			m.append("% ("); //$NON-NLS-1$
+			m.append(cmpstr);
+			m.append("/"); //$NON-NLS-1$
+			m.append(twstr);
+			m.append(")"); //$NON-NLS-1$
+
+			task.subTask(m.toString());
+		}
+		lastWorked = cmp;
+		task.worked(work);
+	}
+
+	public void endTask() {
+		if (task != null) {
+			try {
+				task.done();
+			} finally {
+				task = null;
+			}
+		}
+	}
+
+	public boolean isCancelled() {
+		if (task != null)
+			return task.isCanceled();
+		return root.isCanceled();
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/FileChecker.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/FileChecker.java
index b0f4165..e74fc59 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/FileChecker.java
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/FileChecker.java
@@ -16,7 +16,7 @@
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IWorkspaceRoot;
 import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.egit.core.project.RepositoryMapping;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
 import org.eclipse.jgit.lib.Repository;
 
 /**
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/GitCorePreferenceInitializer.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/GitCorePreferenceInitializer.java
new file mode 100644
index 0000000..2b7390a
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/GitCorePreferenceInitializer.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (C) 2008, Roger C. Soares <rogersoares@intelinet.com.br>
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
+ * Copyright (C) 2013, Matthias Sohn <matthias.sohn@sap.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal;
+
+import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
+import org.eclipse.core.runtime.preferences.DefaultScope;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+
+/** Initializes plugin preferences with default values. */
+public class GitCorePreferenceInitializer extends AbstractPreferenceInitializer {
+	private static final int MB = 1024 * 1024;
+
+	public void initializeDefaultPreferences() {
+		final IEclipsePreferences p  = DefaultScope.INSTANCE.getNode(Activator.getPluginId());
+
+		p.putInt(GitCorePreferences.core_packedGitWindowSize, 8 * 1024);
+		p.putInt(GitCorePreferences.core_packedGitLimit, 10 * MB);
+		p.putBoolean(GitCorePreferences.core_packedGitMMAP, false);
+		p.putInt(GitCorePreferences.core_deltaBaseCacheLimit, 10 * MB);
+		p.putInt(GitCorePreferences.core_streamFileThreshold, 50 * MB);
+		p.putBoolean(GitCorePreferences.core_autoShareProjects, true);
+		p.putBoolean(GitCorePreferences.core_autoIgnoreDerivedResources, true);
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/GitCorePreferences.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/GitCorePreferences.java
new file mode 100644
index 0000000..6d39491
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/GitCorePreferences.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
+ * Copyright (C) 2011, Robin Rosenberg
+ * Copyright (C) 2013, Matthias Sohn <matthias.sohn@sap.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal;
+
+/** Preferences used by the core plugin. */
+public class GitCorePreferences {
+	/** */
+	public static final String core_packedGitWindowSize =
+		"core_packedGitWindowSize";  //$NON-NLS-1$
+	/** */
+	public static final String core_packedGitLimit =
+		"core_packedGitLimit";  //$NON-NLS-1$
+	/** */
+	public static final String core_packedGitMMAP =
+		"core_packedGitMMAP";  //$NON-NLS-1$
+	/** */
+	public static final String core_deltaBaseCacheLimit =
+		"core_deltaBaseCacheLimit";  //$NON-NLS-1$
+	/** */
+	public static final String core_streamFileThreshold =
+		"core_streamFileThreshold"; //$NON-NLS-1$
+	/** */
+	public static final String core_autoShareProjects =
+		"core_autoShareProjects";  //$NON-NLS-1$
+	/** */
+	public static final String core_autoIgnoreDerivedResources =
+		"core_autoIgnoreDerivedResources"; //$NON-NLS-1$
+	/** */
+	public static final String core_gitPrefix =
+		"core_gitPrefix"; //$NON-NLS-1$
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/GitMoveDeleteHook.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/GitMoveDeleteHook.java
new file mode 100644
index 0000000..a2ad039
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/GitMoveDeleteHook.java
@@ -0,0 +1,437 @@
+/*******************************************************************************
+ * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
+ * Copyright (C) 2007, Shawn O. Pearce <spearce@spearce.org>
+ * Copyright (C) 2008, Google Inc.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+
+import org.eclipse.core.filesystem.URIUtil;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.team.IMoveDeleteHook;
+import org.eclipse.core.resources.team.IResourceTree;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.egit.core.internal.indexdiff.IndexDiffCache;
+import org.eclipse.egit.core.internal.indexdiff.IndexDiffCacheEntry;
+import org.eclipse.egit.core.internal.indexdiff.IndexDiffData;
+import org.eclipse.egit.core.internal.project.GitProjectData;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.jgit.dircache.DirCache;
+import org.eclipse.jgit.dircache.DirCacheBuilder;
+import org.eclipse.jgit.dircache.DirCacheEditor;
+import org.eclipse.jgit.dircache.DirCacheEntry;
+import org.eclipse.team.core.RepositoryProvider;
+import org.eclipse.team.core.TeamException;
+
+class GitMoveDeleteHook implements IMoveDeleteHook {
+	private static final boolean I_AM_DONE = true;
+
+	private static final boolean FINISH_FOR_ME = false;
+
+	private final GitProjectData data;
+
+	GitMoveDeleteHook(final GitProjectData d) {
+		Assert.isNotNull(d);
+		data = d;
+	}
+
+	public boolean deleteFile(final IResourceTree tree, final IFile file,
+			final int updateFlags, final IProgressMonitor monitor) {
+		// Linked resources are not files, hence not tracked by git
+		if (file.isLinked())
+			return false;
+
+		final boolean force = (updateFlags & IResource.FORCE) == IResource.FORCE;
+		if (!force && !tree.isSynchronized(file, IResource.DEPTH_ZERO))
+			return false;
+
+		final RepositoryMapping map = RepositoryMapping.getMapping(file);
+		if (map == null)
+			return false;
+
+		String repoRelativePath = map.getRepoRelativePath(file);
+		IndexDiffCache indexDiffCache = Activator.getDefault()
+				.getIndexDiffCache();
+		IndexDiffCacheEntry indexDiffCacheEntry = indexDiffCache
+				.getIndexDiffCacheEntry(map.getRepository());
+		IndexDiffData indexDiff = indexDiffCacheEntry.getIndexDiff();
+		if (indexDiff != null) {
+			if (indexDiff.getUntracked().contains(repoRelativePath))
+				return false;
+			if (indexDiff.getIgnoredNotInIndex().contains(repoRelativePath))
+				return false;
+		}
+		if (!file.exists())
+			return false;
+		if (file.isDerived())
+			return false;
+
+		DirCache dirc = null;
+		try {
+			dirc = map.getRepository().lockDirCache();
+			final int first = dirc.findEntry(repoRelativePath);
+			if (first < 0) {
+				dirc.unlock();
+				return false;
+			}
+
+			final DirCacheBuilder edit = dirc.builder();
+			if (first > 0)
+				edit.keep(0, first);
+			final int next = dirc.nextEntry(first);
+			if (next < dirc.getEntryCount())
+				edit.keep(next, dirc.getEntryCount() - next);
+			if (!edit.commit())
+				tree.failed(new Status(IStatus.ERROR, Activator.getPluginId(),
+						0, CoreText.MoveDeleteHook_operationError, null));
+			tree.standardDeleteFile(file, updateFlags, monitor);
+		} catch (IOException e) {
+			tree.failed(new Status(IStatus.ERROR, Activator.getPluginId(), 0,
+					CoreText.MoveDeleteHook_operationError, e));
+		} finally {
+			if (dirc != null)
+				dirc.unlock();
+		}
+		return true;
+	}
+
+	public boolean deleteFolder(final IResourceTree tree, final IFolder folder,
+			final int updateFlags, final IProgressMonitor monitor) {
+		// Deleting a GIT repository which is in use is a pretty bad idea. To
+		// delete disconnect the team provider first.
+		//
+		if (data.isProtected(folder)) {
+			return cannotModifyRepository(tree);
+		} else {
+			return FINISH_FOR_ME;
+		}
+	}
+
+	public boolean deleteProject(final IResourceTree tree,
+			final IProject project, final int updateFlags,
+			final IProgressMonitor monitor) {
+		// TODO: Note that eclipse thinks folders are real, while
+		// Git does not care.
+		return FINISH_FOR_ME;
+	}
+
+	public boolean moveFile(final IResourceTree tree, final IFile srcf,
+			final IFile dstf, final int updateFlags,
+			final IProgressMonitor monitor) {
+		final boolean force = (updateFlags & IResource.FORCE) == IResource.FORCE;
+		if (!force && !tree.isSynchronized(srcf, IResource.DEPTH_ZERO))
+			return false;
+
+		final RepositoryMapping srcm = RepositoryMapping.getMapping(srcf);
+		if (srcm == null)
+			return false;
+		final RepositoryMapping dstm = RepositoryMapping.getMapping(dstf);
+
+		DirCache sCache = null;
+		try {
+			sCache = srcm.getRepository().lockDirCache();
+			final String sPath = srcm.getRepoRelativePath(srcf);
+			final DirCacheEntry sEnt = sCache.getEntry(sPath);
+			if (sEnt == null)
+				return FINISH_FOR_ME;
+
+			if (!sEnt.isMerged()) {
+				tree.failed(new Status(IStatus.WARNING, Activator.getPluginId(),
+						CoreText.MoveDeleteHook_unmergedFileError));
+				return I_AM_DONE;
+			}
+
+			final DirCacheEditor sEdit = sCache.editor();
+			sEdit.add(new DirCacheEditor.DeletePath(sEnt));
+			if (dstm != null && dstm.getRepository() == srcm.getRepository()) {
+				final String dPath = srcm.getRepoRelativePath(dstf);
+				sEdit.add(new DirCacheEditor.PathEdit(dPath) {
+					@Override
+					public void apply(final DirCacheEntry dEnt) {
+						dEnt.copyMetaData(sEnt);
+					}
+				});
+			}
+			if (!sEdit.commit())
+				tree.failed(new Status(IStatus.ERROR, Activator.getPluginId(),
+						0, CoreText.MoveDeleteHook_operationError, null));
+
+			tree.standardMoveFile(srcf, dstf, updateFlags, monitor);
+		} catch (IOException e) {
+			tree.failed(new Status(IStatus.ERROR, Activator.getPluginId(), 0,
+					CoreText.MoveDeleteHook_operationError, e));
+		} finally {
+			if (sCache != null)
+				sCache.unlock();
+		}
+		return I_AM_DONE;
+	}
+
+	public boolean moveFolder(final IResourceTree tree, final IFolder srcf,
+			final IFolder dstf, final int updateFlags,
+			final IProgressMonitor monitor) {
+		final boolean force = (updateFlags & IResource.FORCE) == IResource.FORCE;
+		if (!force && !tree.isSynchronized(srcf, IResource.DEPTH_ZERO))
+			return false;
+
+		final RepositoryMapping srcm = RepositoryMapping.getMapping(srcf);
+		if (srcm == null)
+			return false;
+		final RepositoryMapping dstm = RepositoryMapping.getMapping(dstf);
+
+		try {
+			final String sPath = srcm.getRepoRelativePath(srcf);
+			if (dstm != null && dstm.getRepository() == srcm.getRepository()) {
+				final String dPath =
+					srcm.getRepoRelativePath(dstf) + "/"; //$NON-NLS-1$
+				MoveResult result = moveIndexContent(dPath, srcm, sPath);
+				switch (result) {
+				case SUCCESS:
+					break;
+				case FAILED:
+					tree.failed(new Status(IStatus.ERROR, Activator.getPluginId(),
+							0, CoreText.MoveDeleteHook_operationError, null));
+					return I_AM_DONE;
+				case UNTRACKED:
+					// we are not responsible for moving untracked files
+					return FINISH_FOR_ME;
+				case UNMERGED:
+					tree.failed(new Status(IStatus.WARNING, Activator.getPluginId(),
+							CoreText.MoveDeleteHook_unmergedFileInFolderError));
+					return I_AM_DONE;
+				}
+			}
+			tree.standardMoveFolder(srcf, dstf, updateFlags, monitor);
+		} catch (IOException e) {
+			tree.failed(new Status(IStatus.ERROR, Activator.getPluginId(), 0,
+					CoreText.MoveDeleteHook_operationError, e));
+		}
+		return true;
+	}
+
+	private void mapProject(final IProject source,
+			final IProjectDescription description,
+			final IProgressMonitor monitor, IPath gitDir) throws CoreException,
+			TeamException {
+		IProject destination = source.getWorkspace().getRoot()
+				.getProject(description.getName());
+		GitProjectData projectData = new GitProjectData(destination);
+		RepositoryMapping repositoryMapping = new RepositoryMapping(
+				destination, gitDir.toFile());
+		projectData.setRepositoryMappings(Arrays
+				.asList(repositoryMapping));
+		projectData.store();
+		GitProjectData.add(destination, projectData);
+		RepositoryProvider
+				.map(destination, GitProvider.class.getName());
+		destination.refreshLocal(IResource.DEPTH_INFINITE,
+				new SubProgressMonitor(monitor, 50));
+	}
+
+	private boolean unmapProject(final IResourceTree tree, final IProject source) {
+		// The Repository mapping does not support moving
+		// projects, so just disconnect/reconnect for now
+		try {
+			RepositoryProvider.unmap(source);
+		} catch (TeamException e) {
+			tree.failed(new Status(IStatus.ERROR, Activator
+					.getPluginId(), 0,
+					CoreText.MoveDeleteHook_operationError, e));
+					return true; // Do not let Eclipse complete the operation
+		}
+		return false;
+	}
+
+	public boolean moveProject(final IResourceTree tree, final IProject source,
+			final IProjectDescription description, final int updateFlags,
+			final IProgressMonitor monitor) {
+		final RepositoryMapping srcm = RepositoryMapping.getMapping(source);
+		if (srcm == null)
+			return false;
+		IPath newLocation = null;
+		if (description.getLocationURI() != null)
+			newLocation = URIUtil.toPath(description.getLocationURI());
+		else
+			newLocation = source.getWorkspace().getRoot().getLocation()
+					.append(description.getName());
+		IPath sourceLocation = source.getLocation();
+		// Prevent a serious error.
+		if (sourceLocation.isPrefixOf(newLocation)
+				&& sourceLocation.segmentCount() != newLocation.segmentCount()
+				&& !"true".equals(System.getProperty("egit.assume_307140_fixed"))) { //$NON-NLS-1$//$NON-NLS-2$
+			// Graceful handling of bug, i.e. refuse to destroy your code
+			tree.failed(new Status(
+					IStatus.ERROR,
+					Activator.getPluginId(),
+					0,
+					"Cannot move project. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=307140 (not resolved in 3.7)", //$NON-NLS-1$
+					null));
+			return true;
+		}
+		File newLocationFile = newLocation.toFile();
+		// check if new location is below the same repository
+		Path workTree = new Path(srcm.getRepository().getWorkTree().getAbsolutePath());
+		int matchingFirstSegments = workTree.matchingFirstSegments(newLocation);
+		if (matchingFirstSegments == workTree.segmentCount()) {
+			return moveProjectHelperMoveOnlyProject(tree, source, description, updateFlags,
+					monitor, srcm, newLocationFile);
+		} else {
+			int dstAboveSrcRepo = newLocation.matchingFirstSegments(RepositoryMapping
+					.getMapping(source).getGitDirAbsolutePath());
+			int srcAboveSrcRepo = sourceLocation.matchingFirstSegments(RepositoryMapping.getMapping(source).getGitDirAbsolutePath());
+			if (dstAboveSrcRepo > 0 && srcAboveSrcRepo > 0) {
+				return moveProjectHelperMoveRepo(tree, source, description, updateFlags, monitor,
+					srcm, newLocation, sourceLocation);
+			} else {
+				return FINISH_FOR_ME;
+			}
+		}
+	}
+
+	private boolean moveProjectHelperMoveOnlyProject(final IResourceTree tree,
+			final IProject source, final IProjectDescription description,
+			final int updateFlags, final IProgressMonitor monitor,
+			final RepositoryMapping srcm, File newLocationFile) {
+		final String sPath = srcm.getRepoRelativePath(source);
+		final String absoluteWorkTreePath = srcm.getRepository().getWorkTree().getAbsolutePath();
+		final String newLocationAbsolutePath = newLocationFile.getAbsolutePath();
+		final String dPath;
+		if (newLocationAbsolutePath.equals(absoluteWorkTreePath))
+			dPath = ""; //$NON-NLS-1$
+		else
+			dPath = new Path(
+					newLocationAbsolutePath.substring(absoluteWorkTreePath
+							.length() + 1) + "/").toPortableString(); //$NON-NLS-1$
+		try {
+			IPath gitDir = srcm.getGitDirAbsolutePath();
+			if (unmapProject(tree, source))
+				return true;
+
+			monitor.worked(100);
+
+			MoveResult result = moveIndexContent(dPath, srcm, sPath);
+			switch (result) {
+			case SUCCESS:
+				break;
+			case FAILED:
+				tree.failed(new Status(IStatus.ERROR, Activator
+						.getPluginId(), 0,
+						CoreText.MoveDeleteHook_operationError, null));
+				break;
+			case UNTRACKED:
+				// we are not responsible for moving untracked files
+				return FINISH_FOR_ME;
+			case UNMERGED:
+				tree.failed(new Status(IStatus.WARNING, Activator.getPluginId(),
+						CoreText.MoveDeleteHook_unmergedFileInFolderError));
+				return I_AM_DONE;
+			}
+
+			tree.standardMoveProject(source, description, updateFlags,
+					monitor);
+
+			// Reconnect
+			mapProject(
+					source.getWorkspace().getRoot()
+							.getProject(description.getName()),
+					description, monitor, gitDir);
+		} catch (IOException e) {
+			tree.failed(new Status(IStatus.ERROR, Activator.getPluginId(),
+					0, CoreText.MoveDeleteHook_operationError, e));
+		} catch (CoreException e) {
+			tree.failed(new Status(IStatus.ERROR, Activator.getPluginId(),
+					0, CoreText.MoveDeleteHook_operationError, e));
+		}
+		return true;
+	}
+
+	private boolean moveProjectHelperMoveRepo(final IResourceTree tree, final IProject source,
+			final IProjectDescription description, final int updateFlags,
+			final IProgressMonitor monitor, final RepositoryMapping srcm,
+			IPath newLocation, IPath sourceLocation) {
+		// Moving repo, we need to unplug the previous location and
+		// Re-plug it again with the new location.
+		IPath gitDir = srcm.getGitDirAbsolutePath();
+		if (unmapProject(tree, source))
+			return true; // Error information in tree
+
+		monitor.worked(100);
+
+		IPath relativeGitDir = gitDir.makeRelativeTo(sourceLocation);
+		tree.standardMoveProject(source, description, updateFlags,
+				monitor);
+
+		IPath newGitDir = newLocation.append(relativeGitDir);
+		// Reconnect
+		try {
+			mapProject(source, description, monitor, newGitDir);
+		} catch (CoreException e) {
+			tree.failed(new Status(IStatus.ERROR, Activator.getPluginId(),
+					0, CoreText.MoveDeleteHook_operationError, e));
+		}
+		return true; // We're done with the move
+	}
+
+	enum MoveResult { SUCCESS, FAILED, UNTRACKED, UNMERGED }
+
+	private MoveResult moveIndexContent(String dPath,
+			final RepositoryMapping srcm, final String sPath) throws IOException {
+
+		final DirCache sCache = srcm.getRepository().lockDirCache();
+		try {
+			final DirCacheEntry[] sEnt = sCache.getEntriesWithin(sPath);
+			if (sEnt.length == 0) {
+				sCache.unlock();
+				return MoveResult.UNTRACKED;
+			}
+
+			final DirCacheEditor sEdit = sCache.editor();
+			sEdit.add(new DirCacheEditor.DeleteTree(sPath));
+			final int sPathLen = sPath.length() == 0 ? sPath.length() : sPath
+					.length() + 1;
+			for (final DirCacheEntry se : sEnt) {
+				if (!se.isMerged())
+					return MoveResult.UNMERGED;
+				final String p = se.getPathString().substring(sPathLen);
+				sEdit.add(new DirCacheEditor.PathEdit(dPath + p) {
+					@Override
+					public void apply(final DirCacheEntry dEnt) {
+						dEnt.copyMetaData(se);
+					}
+				});
+			}
+			if (sEdit.commit())
+				return MoveResult.SUCCESS;
+			else
+				return MoveResult.FAILED;
+		} finally {
+			if (sCache != null)
+				sCache.unlock();
+		}
+	}
+
+	private boolean cannotModifyRepository(final IResourceTree tree) {
+		tree.failed(new Status(IStatus.ERROR, Activator.getPluginId(), 0,
+				CoreText.MoveDeleteHook_cannotModifyFolder, null));
+		return I_AM_DONE;
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/GitProjectSetCapability.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/GitProjectSetCapability.java
new file mode 100644
index 0000000..11e10aa
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/GitProjectSetCapability.java
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright (C) 2009, Mykola Nikishov <mn@mn.com.ua>
+ * Copyright (C) 2011, Robin Stocker <robin@nibor.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Manuel Doninger <manuel.doninger@googlemail.com>
+ *     Tomasz Zarna <Tomasz.Zarna@pl.ibm.com>
+ *******************************************************************************/
+package org.eclipse.egit.core.internal;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.jgit.lib.ConfigConstants;
+import org.eclipse.jgit.lib.StoredConfig;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.team.core.ProjectSetCapability;
+import org.eclipse.team.core.ProjectSetSerializationContext;
+import org.eclipse.team.core.TeamException;
+
+/**
+ * Capability for exporting and importing projects shared with Git as part of a
+ * team project set.
+ */
+public final class GitProjectSetCapability extends ProjectSetCapability {
+
+	private static final String VERSION = "1.0"; //$NON-NLS-1$
+
+	@Override
+	public String[] asReference(IProject[] projects,
+			ProjectSetSerializationContext context, IProgressMonitor monitor)
+			throws TeamException {
+		String[] references = new String[projects.length];
+		for (int i = 0; i < projects.length; i++)
+			references[i] = asReference(projects[i]);
+		return references;
+	}
+
+	private String asReference(IProject project) throws TeamException {
+		RepositoryMapping mapping = RepositoryMapping.getMapping(project);
+		String branch;
+		try {
+			branch = mapping.getRepository().getBranch();
+		} catch (IOException e) {
+			throw new TeamException(NLS.bind(
+					CoreText.GitProjectSetCapability_ExportCouldNotGetBranch,
+					project.getName()));
+		}
+		StoredConfig config = mapping.getRepository().getConfig();
+		String remote = config.getString(ConfigConstants.CONFIG_BRANCH_SECTION,
+				branch, ConfigConstants.CONFIG_KEY_REMOTE);
+		String url = config.getString(ConfigConstants.CONFIG_REMOTE_SECTION,
+				remote, ConfigConstants.CONFIG_KEY_URL);
+		if (url == null)
+			throw new TeamException(NLS.bind(
+					CoreText.GitProjectSetCapability_ExportNoRemote,
+					project.getName()));
+
+		String projectPath = mapping.getRepoRelativePath(project);
+		if (projectPath.equals("")) //$NON-NLS-1$
+			projectPath = "."; //$NON-NLS-1$
+
+		return asReference(url, branch, projectPath);
+	}
+
+	private String asReference(String url, String branch, String projectPath) {
+		StringBuilder sb = new StringBuilder();
+
+		sb.append(VERSION);
+		sb.append(ProjectReference.SEPARATOR);
+		sb.append(url);
+		sb.append(ProjectReference.SEPARATOR);
+		sb.append(branch);
+		sb.append(ProjectReference.SEPARATOR);
+		sb.append(projectPath);
+
+		return sb.toString();
+	}
+
+	@Override
+	public IProject[] addToWorkspace(final String[] referenceStrings,
+			final ProjectSetSerializationContext context,
+			final IProgressMonitor monitor) throws TeamException {
+		final ArrayList<IProject> importedProjects = new ArrayList<IProject>();
+
+		try{
+			ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
+				public void run(IProgressMonitor wsOpMonitor) throws CoreException {
+					ProjectReferenceImporter importer = new ProjectReferenceImporter(referenceStrings);
+					List<IProject> p = importer.run(wsOpMonitor);
+					importedProjects.addAll(p);
+				}
+			}, ResourcesPlugin.getWorkspace().getRoot(), IWorkspace.AVOID_UPDATE, monitor);
+		} catch (CoreException e) {
+			throw TeamException.asTeamException(e);
+		}
+		final IProject[] result = importedProjects
+				.toArray(new IProject[importedProjects.size()]);
+		return result;
+	}
+
+	@Override
+	public String asReference(URI uri, String projectName) {
+		GitURI gitURI = new GitURI(uri);
+		return asReference(gitURI.getRepository().toString(), gitURI.getTag(), gitURI.getPath().toString());
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/GitProvider.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/GitProvider.java
new file mode 100644
index 0000000..52d3341
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/GitProvider.java
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal;
+
+import java.io.IOException;
+
+import org.eclipse.core.resources.IResourceRuleFactory;
+import org.eclipse.core.resources.team.IMoveDeleteHook;
+import org.eclipse.core.resources.team.ResourceRuleFactory;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.egit.core.internal.project.GitProjectData;
+import org.eclipse.egit.core.internal.storage.GitFileHistoryProvider;
+import org.eclipse.team.core.RepositoryProvider;
+import org.eclipse.team.core.history.IFileHistoryProvider;
+
+/**
+ * The Team provider class for a Git repository.
+ */
+public class GitProvider extends RepositoryProvider {
+
+	/**
+	 * Id of repository provider
+	 *
+	 * @see #getID()
+	 */
+	public static final String ID = "org.eclipse.egit.core.GitProvider"; //$NON-NLS-1$
+
+	private GitProjectData data;
+
+	private GitMoveDeleteHook hook;
+
+	private GitFileHistoryProvider historyProvider;
+
+	private final IResourceRuleFactory resourceRuleFactory = new GitResourceRuleFactory();
+
+	public String getID() {
+		return ID;
+	}
+
+	public void configureProject() throws CoreException {
+		getData().markTeamPrivateResources();
+	}
+
+	public void deconfigure() throws CoreException {
+		try {
+			GitProjectData.delete(getProject());
+		} catch (IOException e) {
+			throw new CoreException(new Status(IStatus.ERROR,
+					Activator.getPluginId(), e.getMessage(), e));
+		}
+	}
+
+	public boolean canHandleLinkedResources() {
+		return true;
+	}
+
+	@Override
+	public boolean canHandleLinkedResourceURI() {
+		return true;
+	}
+
+	public synchronized IMoveDeleteHook getMoveDeleteHook() {
+		if (hook == null) {
+			GitProjectData _data = getData();
+			if (_data != null)
+				hook = new GitMoveDeleteHook(_data);
+		}
+		return hook;
+	}
+
+	/**
+	 * @return information about the mapping of an Eclipse project
+	 * to a Git repository.
+	 */
+	public synchronized GitProjectData getData() {
+		if (data == null) {
+			data = GitProjectData.get(getProject());
+		}
+		return data;
+	}
+
+	public synchronized IFileHistoryProvider getFileHistoryProvider() {
+		if (historyProvider == null) {
+			historyProvider = new GitFileHistoryProvider();
+		}
+		return historyProvider;
+	}
+
+	@Override
+	public IResourceRuleFactory getRuleFactory() {
+		return resourceRuleFactory;
+	}
+
+	private static class GitResourceRuleFactory extends ResourceRuleFactory {
+		// Use the default rule factory instead of the
+		// pessimistic one by default.
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/GitRepositoryProviderType.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/GitRepositoryProviderType.java
index f995785..215c878 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/GitRepositoryProviderType.java
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/GitRepositoryProviderType.java
@@ -14,11 +14,9 @@
 import java.io.IOException;
 
 import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.GitProjectSetCapability;
-import org.eclipse.egit.core.synchronize.GitResourceVariantTreeSubscriber;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
+import org.eclipse.egit.core.internal.synchronize.GitResourceVariantTreeSubscriber;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeData;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeDataSet;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.team.core.ProjectSetCapability;
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/GitTag.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/GitTag.java
new file mode 100644
index 0000000..35d6a95
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/GitTag.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
+ * Copyright (C) 2007, Shawn O. Pearce <spearce@spearce.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal;
+
+import org.eclipse.team.core.history.ITag;
+
+/**
+ * A representation of a Git tag in Eclipse.
+ */
+public class GitTag implements ITag {
+
+	private String name;
+
+	/**
+	 * Construct a GitTag object with a given name.
+	 *
+	 * @param name the Git tag name
+	 */
+	public GitTag(String name) {
+		this.name = name;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/GitURI.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/GitURI.java
index c0af033..2ab7f5d 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/GitURI.java
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/GitURI.java
@@ -16,8 +16,6 @@
 
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.CoreText;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.transport.URIish;
 import org.eclipse.osgi.util.NLS;
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/IteratorService.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/IteratorService.java
new file mode 100644
index 0000000..adf02a4
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/IteratorService.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (C) 2010, 2012 Jens Baumgart <jens.baumgart@sap.com> and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal;
+
+import java.io.File;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.treewalk.WorkingTreeIterator;
+
+/**
+ * IteratorService is a utility class for providing the right
+ * {@link WorkingTreeIterator} iterator for a given folder.
+ *
+ */
+public class IteratorService {
+
+	/**
+	 * Creates a {@link WorkingTreeIterator} for a tree walk starting on the
+	 * repository work tree folder.
+	 *
+	 * @param repository
+	 * @return <li>a {@link ContainerTreeIterator} if the work tree folder of
+	 *         the given repository resides in a project shared with Git <li>an
+	 *         {@link AdaptableFileTreeIterator} otherwise <li>{@code null} if the
+	 *         workspace is closed.
+	 */
+	public static WorkingTreeIterator createInitialIterator(
+			Repository repository) {
+		IWorkspaceRoot root;
+		try {
+			root = ResourcesPlugin.getWorkspace().getRoot();
+		} catch (IllegalStateException e) {
+			// workspace is closed
+			return null;
+		}
+		IContainer container = findContainer(root, repository.getWorkTree());
+		if (container != null)
+			return new ContainerTreeIterator(repository, container);
+		return new AdaptableFileTreeIterator(repository, root);
+	}
+
+	/**
+	 * The method searches a container resource related to the given file. The
+	 * container must reside in a project that is shared with Git. Linked folders
+	 * are ignored.
+	 *
+	 * @param root
+	 *            the workspace root
+	 * @param file
+	 * @return a container that matches the description above or null if such a
+	 *         container does not exist
+	 */
+	public static IContainer findContainer(IWorkspaceRoot root, File file) {
+		if (!file.isDirectory())
+			throw new IllegalArgumentException(
+					"file " + file.getAbsolutePath() + " is no directory"); //$NON-NLS-1$//$NON-NLS-2$
+		final IContainer[] containers = root.findContainersForLocationURI(file
+				.toURI());
+		for (IContainer container : containers)
+			if (container.isAccessible()
+					&& !container.isLinked(IResource.CHECK_ANCESTORS)
+					&& isProjectSharedWithGit(container))
+				return container;
+		return null;
+	}
+
+	private static boolean isProjectSharedWithGit(IContainer container) {
+		return RepositoryMapping.getMapping(container) != null;
+	}
+
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/JobFamilies.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/JobFamilies.java
new file mode 100644
index 0000000..a0a135f
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/JobFamilies.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (C) 2011, 2013 Matthias Sohn <matthias.sohn@sap.com> and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal;
+
+/**
+ * Job families of EGit jobs. May be used in tests to join job execution.
+ *
+ */
+public class JobFamilies {
+
+	/**
+	 * Job family for Repository changed job
+	 */
+	public static final Object REPOSITORY_CHANGED = new Object();
+
+	/**
+	 * Job family for Index Diff Cache update
+	 */
+	public static final Object INDEX_DIFF_CACHE_UPDATE = new Object();
+
+	/**
+	 * Job family for auto share job
+	 */
+	public static final Object AUTO_SHARE = new Object();
+
+	/**
+	 * Job family for auto ignore job
+	 */
+	public static final Object AUTO_IGNORE = new Object();
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/ProjectReference.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/ProjectReference.java
new file mode 100644
index 0000000..8574476
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/ProjectReference.java
@@ -0,0 +1,149 @@
+/*******************************************************************************
+ * Copyright (C) 2009, Mykola Nikishov <mn@mn.com.ua>
+ * Copyright (C) 2011, Robin Stocker <robin@nibor.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Manuel Doninger <manuel.doninger@googlemail.com>
+ *******************************************************************************/
+package org.eclipse.egit.core.internal;
+
+import java.net.URISyntaxException;
+import java.util.regex.Pattern;
+
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.transport.URIish;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * ProjectReference for Team project sets
+ */
+public final class ProjectReference {
+
+	private static final String DEFAULT_BRANCH = Constants.MASTER;
+
+	/**
+	 * the version of the reference string
+	 */
+	private String version;
+
+	/**
+	 * a relative path (from the repository root) to a project
+	 */
+	private String projectDir;
+
+	/**
+	 * <code>repository</code> parameter
+	 */
+	private URIish repository;
+
+	/**
+	 * the remote branch that will be checked out, see <code>--branch</code>
+	 * option
+	 */
+	private String branch = DEFAULT_BRANCH;
+
+	/**
+	 * use this name instead of using the remote name origin to keep track
+	 * of the upstream repository, see <code>--origin</code> option.
+	 */
+	private String origin = Constants.DEFAULT_REMOTE_NAME;
+
+	static final String SEPARATOR = ","; //$NON-NLS-1$
+
+	/**
+	 * @param reference
+	 * @throws URISyntaxException
+	 * @throws IllegalArgumentException
+	 */
+	@SuppressWarnings("boxing")
+	public ProjectReference(final String reference) throws URISyntaxException, IllegalArgumentException {
+		final String[] tokens = reference.split(Pattern.quote(ProjectReference.SEPARATOR));
+		if (tokens.length != 4)
+			throw new IllegalArgumentException(NLS.bind(
+					CoreText.ProjectReference_InvalidTokensCount, new Object[] {
+							4, tokens.length, tokens }));
+
+		this.version = tokens[0];
+		this.repository = new URIish(tokens[1]);
+		if (!"".equals(tokens[2])) //$NON-NLS-1$
+			this.branch = tokens[2];
+		this.projectDir = tokens[3];
+	}
+
+	/**
+	 * @return <code>repository</code> parameter
+	 */
+	public URIish getRepository() {
+		return repository;
+	}
+
+	/**
+	 * @return the remote branch that will be checked out, see <code>--branch</code>
+	 * option
+	 */
+	public String getBranch() {
+		return branch;
+	}
+
+	/**
+	 * @return name of the upstream repository
+	 */
+	public String getOrigin() {
+		return origin;
+	}
+
+	/**
+	 * @return a relative path (from the repository root) to a project
+	 */
+	public String getProjectDir() {
+		return projectDir;
+	}
+
+	String getVersion() {
+		return version;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((branch == null) ? 0 : branch.hashCode());
+		result = prime * result
+				+ ((projectDir == null) ? 0 : projectDir.hashCode());
+		result = prime * result
+				+ ((repository == null) ? 0 : repository.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (!(obj instanceof ProjectReference))
+			return false;
+		ProjectReference other = (ProjectReference) obj;
+		if (branch == null) {
+			if (other.branch != null)
+				return false;
+		} else if (!branch.equals(other.branch))
+			return false;
+		if (projectDir == null) {
+			if (other.projectDir != null)
+				return false;
+		} else if (!projectDir.equals(other.projectDir))
+			return false;
+		if (repository == null) {
+			if (other.repository != null)
+				return false;
+		} else if (!repository.equals(other.repository))
+			return false;
+		return true;
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/ProjectReferenceImporter.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/ProjectReferenceImporter.java
index 11f2a53..d248dfa 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/ProjectReferenceImporter.java
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/ProjectReferenceImporter.java
@@ -32,12 +32,8 @@
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.CoreText;
-import org.eclipse.egit.core.ProjectReference;
-import org.eclipse.egit.core.RepositoryUtil;
-import org.eclipse.egit.core.op.CloneOperation;
-import org.eclipse.egit.core.op.ConnectProviderOperation;
+import org.eclipse.egit.core.internal.op.CloneOperation;
+import org.eclipse.egit.core.internal.op.ConnectProviderOperation;
 import org.eclipse.jgit.lib.Config;
 import org.eclipse.jgit.lib.ConfigConstants;
 import org.eclipse.jgit.lib.Constants;
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/RepositoryCache.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/RepositoryCache.java
new file mode 100644
index 0000000..f194693
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/RepositoryCache.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Jens Baumgart <jens.baumgart@sap.com>
+ * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
+ * Copyright (C) 2008, Google Inc.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.internal.storage.file.FileRepository;
+
+/**
+ * Central cache for Repository instances
+ *
+ */
+public class RepositoryCache {
+	private final Map<File, Reference<Repository>> repositoryCache = new HashMap<File, Reference<Repository>>();
+
+	RepositoryCache() {
+		// package private constructor
+	}
+
+	/**
+	 *
+	 * @param gitDir
+	 * @return an existing instance of Repository for <code>gitDir</code> or a
+	 *         new one if no Repository instance for <code>gitDir</code> exists
+	 *         in the cache.
+	 * @throws IOException
+	 */
+	public synchronized Repository lookupRepository(final File gitDir)
+			throws IOException {
+		prune(repositoryCache);
+		Reference<Repository> r = repositoryCache.get(gitDir);
+		Repository d = r != null ? r.get() : null;
+		if (d == null) {
+			d = new FileRepository(gitDir);
+			repositoryCache.put(gitDir, new WeakReference<Repository>(d));
+		}
+		return d;
+	}
+
+	/**
+	 * @return all Repository instances contained in the cache
+	 */
+	public synchronized Repository[] getAllRepositories() {
+		prune(repositoryCache);
+		List<Repository> repositories = new ArrayList<Repository>();
+		for (Reference<Repository> reference : repositoryCache.values()) {
+			repositories.add(reference.get());
+		}
+		return repositories.toArray(new Repository[repositories.size()]);
+	}
+
+	private static void prune(Map<File, Reference<Repository>> map) {
+		for (final Iterator<Map.Entry<File, Reference<Repository>>> i = map.entrySet()
+				.iterator(); i.hasNext();) {
+			Repository repository = i.next().getValue().get();
+			if (repository == null
+					|| !repository.getDirectory().exists())
+				i.remove();
+		}
+	}
+
+	/**
+	 * TESTING ONLY!
+	 * Unit tests can use this method to get a clean beginning state
+	 */
+	public void clear() {
+		repositoryCache.clear();
+	}
+
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/RepositoryUtil.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/RepositoryUtil.java
new file mode 100644
index 0000000..adb3dae
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/RepositoryUtil.java
@@ -0,0 +1,538 @@
+/*******************************************************************************
+ * Copyright (c) 2010 SAP AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Mathias Kinzler (SAP AG) - initial implementation
+ *******************************************************************************/
+package org.eclipse.egit.core.internal;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.TreeSet;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.jgit.api.MergeCommand.FastForwardMode;
+import org.eclipse.jgit.errors.IncorrectObjectTypeException;
+import org.eclipse.jgit.lib.ConfigConstants;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.FileMode;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.lib.RepositoryCache.FileKey;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevObject;
+import org.eclipse.jgit.revwalk.RevTag;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.internal.storage.file.CheckoutEntry;
+import org.eclipse.jgit.internal.storage.file.ReflogEntry;
+import org.eclipse.jgit.internal.storage.file.ReflogReader;
+import org.eclipse.jgit.treewalk.FileTreeIterator;
+import org.eclipse.jgit.treewalk.TreeWalk;
+import org.eclipse.jgit.treewalk.WorkingTreeIterator;
+import org.eclipse.jgit.treewalk.filter.PathFilter;
+import org.eclipse.jgit.util.FS;
+import org.osgi.service.prefs.BackingStoreException;
+
+/**
+ * Utility class for handling Repositories in the UI.
+ */
+public class RepositoryUtil {
+
+	/** The preferences to store the directories known to the Git Repositories view */
+	public static final String PREFS_DIRECTORIES = "GitRepositoriesView.GitDirectories"; //$NON-NLS-1$
+
+	private final Map<String, Map<String, String>> commitMappingCache = new HashMap<String, Map<String, String>>();
+
+	private final Map<String, String> repositoryNameCache = new HashMap<String, String>();
+
+	private final IEclipsePreferences prefs = InstanceScope.INSTANCE
+			.getNode(Activator.getPluginId());
+
+	/**
+	 * Clients should obtain an instance from {@link Activator}
+	 */
+	RepositoryUtil() {
+		// nothing
+	}
+
+	/**
+	 * Used by {@link Activator}
+	 */
+	void dispose() {
+		commitMappingCache.clear();
+		repositoryNameCache.clear();
+	}
+
+	/**
+	 * Tries to map a commit to a symbolic reference.
+	 * <p>
+	 * This value will be cached for the given commit ID unless refresh is
+	 * specified. The return value will be the full name, e.g.
+	 * "refs/remotes/someBranch", "refs/tags/v.1.0"
+	 * <p>
+	 * Since this mapping is not unique, the following precedence rules are
+	 * used:
+	 * <ul>
+	 * <li>Tags take precedence over branches</li>
+	 * <li>Local branches take preference over remote branches</li>
+	 * <li>Newer references take precedence over older ones where time stamps
+	 * are available. Use commiter time stamp from commit if no stamp can be
+	 * found on the tag</li>
+	 * <li>If there are still ambiguities, the reference name with the highest
+	 * lexicographic value will be returned</li>
+	 * </ul>
+	 *
+	 * @param repository
+	 *            the {@link Repository}
+	 * @param commitId
+	 *            a commit
+	 * @param refresh
+	 *            if true, the cache will be invalidated
+	 * @return the symbolic reference, or <code>null</code> if no such reference
+	 *         can be found
+	 */
+	public String mapCommitToRef(Repository repository, String commitId,
+			boolean refresh) {
+		synchronized (commitMappingCache) {
+
+			if (!ObjectId.isId(commitId)) {
+				return null;
+			}
+
+			try {
+				ReflogReader reflogReader = repository.getReflogReader(Constants.HEAD);
+				if (reflogReader != null) {
+					List<ReflogEntry> lastEntry = reflogReader.getReverseEntries();
+					for (ReflogEntry entry : lastEntry) {
+						if (entry.getNewId().name().equals(commitId)) {
+							CheckoutEntry checkoutEntry = entry.parseCheckout();
+							if (checkoutEntry != null) {
+								Ref ref = repository.getRef(checkoutEntry.getToBranch());
+								if (ref != null)
+									ref = repository.peel(ref);
+								if (ref != null) {
+									ObjectId id = ref.getPeeledObjectId();
+									if (id != null && id.getName().equals(commitId))
+										return checkoutEntry.getToBranch();
+								}
+							}
+						}
+					}
+				}
+			} catch (IOException e) {
+				// ignore here
+			}
+
+			Map<String, String> cacheEntry = commitMappingCache.get(repository
+					.getDirectory().toString());
+			if (!refresh && cacheEntry != null
+					&& cacheEntry.containsKey(commitId)) {
+				// this may be null in fact
+				return cacheEntry.get(commitId);
+			}
+			if (cacheEntry == null) {
+				cacheEntry = new HashMap<String, String>();
+				commitMappingCache.put(repository.getDirectory().getPath(),
+						cacheEntry);
+			} else {
+				cacheEntry.clear();
+			}
+
+			Map<String, Date> tagMap = new HashMap<String, Date>();
+			try {
+				RevWalk rw = new RevWalk(repository);
+				Map<String, Ref> tags = repository.getRefDatabase().getRefs(
+						Constants.R_TAGS);
+				for (Ref tagRef : tags.values()) {
+					RevObject any = rw.parseAny(repository.resolve(tagRef.getName()));
+					if (any instanceof RevTag) {
+						RevTag tag = (RevTag) any;
+						if (tag.getObject().name().equals(commitId)) {
+							Date timestamp;
+							if (tag.getTaggerIdent() != null) {
+								timestamp = tag.getTaggerIdent().getWhen();
+							} else {
+								try {
+									RevCommit commit = rw.parseCommit(tag.getObject());
+									timestamp = commit.getCommitterIdent().getWhen();
+								} catch (IncorrectObjectTypeException e) {
+									// not referencing a comit.
+									timestamp = null;
+								}
+							}
+							tagMap.put(tagRef.getName(), timestamp);
+						}
+					} else if (any instanceof RevCommit) {
+						RevCommit commit = ((RevCommit)any);
+						if (commit.name().equals(commitId))
+							tagMap.put(tagRef.getName(), commit.getCommitterIdent().getWhen());
+					} // else ignore here
+				}
+			} catch (IOException e) {
+				// ignore here
+			}
+
+			String cacheValue = null;
+
+			if (!tagMap.isEmpty()) {
+				// we try to obtain the "latest" tag
+				Date compareDate = new Date(0);
+				for (Map.Entry<String, Date> tagEntry : tagMap.entrySet()) {
+					if (tagEntry.getValue() != null
+							&& tagEntry.getValue().after(compareDate)) {
+						compareDate = tagEntry.getValue();
+						cacheValue = tagEntry.getKey();
+					}
+				}
+				// if we don't have time stamps, we sort
+				if (cacheValue == null) {
+					String compareString = ""; //$NON-NLS-1$
+					for (String tagName : tagMap.keySet()) {
+						if (tagName.compareTo(compareString) >= 0) {
+							cacheValue = tagName;
+							compareString = tagName;
+						}
+					}
+				}
+			}
+
+			if (cacheValue == null) {
+				// we didnt't find a tag, so let's look for local branches
+				Set<String> branchNames = new TreeSet<String>();
+				// put this into a sorted set
+				try {
+					Map<String, Ref> remoteBranches = repository
+							.getRefDatabase().getRefs(Constants.R_HEADS);
+					for (Ref branch : remoteBranches.values()) {
+						if (branch.getObjectId().name().equals(commitId)) {
+							branchNames.add(branch.getName());
+						}
+					}
+				} catch (IOException e) {
+					// ignore here
+				}
+				if (!branchNames.isEmpty()) {
+					// get the last (sorted) entry
+					cacheValue = branchNames.toArray(new String[branchNames
+							.size()])[branchNames.size() - 1];
+				}
+			}
+
+			if (cacheValue == null) {
+				// last try: remote branches
+				Set<String> branchNames = new TreeSet<String>();
+				// put this into a sorted set
+				try {
+					Map<String, Ref> remoteBranches = repository
+							.getRefDatabase().getRefs(Constants.R_REMOTES);
+					for (Ref branch : remoteBranches.values()) {
+						if (branch.getObjectId().name().equals(commitId)) {
+							branchNames.add(branch.getName());
+						}
+					}
+					if (!branchNames.isEmpty()) {
+						// get the last (sorted) entry
+						cacheValue = branchNames.toArray(new String[branchNames
+								.size()])[branchNames.size() - 1];
+					}
+				} catch (IOException e) {
+					// ignore here
+				}
+			}
+			cacheEntry.put(commitId, cacheValue);
+			return cacheValue;
+		}
+	}
+
+	/**
+	 * Return a cached UI "name" for a Repository
+	 * <p>
+	 * This uses the name of the parent of the repository's directory.
+	 *
+	 * @param repository
+	 * @return the name
+	 */
+	public String getRepositoryName(final Repository repository) {
+		File gitDir = repository.getDirectory();
+		if (gitDir == null)
+			return ""; //$NON-NLS-1$
+
+		// Use parent file for non-bare repositories
+		if (!repository.isBare()) {
+			gitDir = gitDir.getParentFile();
+			if (gitDir == null)
+				return ""; //$NON-NLS-1$
+		}
+
+		synchronized (repositoryNameCache) {
+			final String path = gitDir.getPath().toString();
+			String name = repositoryNameCache.get(path);
+			if (name != null)
+				return name;
+			name = gitDir.getName();
+			repositoryNameCache.put(path, name);
+			return name;
+		}
+	}
+
+	/**
+	 * @return the underlying preferences
+	 */
+	public IEclipsePreferences getPreferences() {
+		return prefs;
+	}
+
+	private Set<String> getRepositories() {
+		String dirs;
+		synchronized (prefs) {
+			dirs = prefs.get(PREFS_DIRECTORIES, ""); //$NON-NLS-1$
+		}
+		if (dirs == null || dirs.length() == 0)
+			return Collections.emptySet();
+		Set<String> configuredStrings = new HashSet<String>();
+		StringTokenizer tok = new StringTokenizer(dirs, File.pathSeparator);
+		while (tok.hasMoreTokens())
+			configuredStrings.add(tok.nextToken());
+		return configuredStrings;
+	}
+
+	/**
+	 *
+	 * @return the list of configured Repository paths; will be sorted
+	 */
+	public List<String> getConfiguredRepositories() {
+		final List<String> repos = new ArrayList<String>(getRepositories());
+		Collections.sort(repos);
+		return repos;
+	}
+
+	private String getPath(File repositoryDir) {
+		try {
+			return repositoryDir.getCanonicalPath();
+		} catch (IOException e) {
+			return repositoryDir.getAbsolutePath();
+		}
+	}
+
+	/**
+	 *
+	 * @param repositoryDir
+	 *            the Repository path
+	 * @return <code>true</code> if the repository path was not yet configured
+	 * @throws IllegalArgumentException
+	 *             if the path does not "look" like a Repository
+	 */
+	public boolean addConfiguredRepository(File repositoryDir)
+			throws IllegalArgumentException {
+		synchronized (prefs) {
+
+			if (!FileKey.isGitRepository(repositoryDir, FS.DETECTED))
+				throw new IllegalArgumentException();
+
+			String dirString = getPath(repositoryDir);
+
+			List<String> dirStrings = getConfiguredRepositories();
+			if (dirStrings.contains(dirString)) {
+				return false;
+			} else {
+				Set<String> dirs = new HashSet<String>();
+				dirs.addAll(dirStrings);
+				dirs.add(dirString);
+				saveDirs(dirs);
+				return true;
+			}
+		}
+	}
+
+	/**
+	 * @param file
+	 * @return <code>true</code> if the configuration was changed by the remove
+	 */
+	public boolean removeDir(File file) {
+		synchronized (prefs) {
+
+			String dir = getPath(file);
+
+			Set<String> dirStrings = new HashSet<String>();
+			dirStrings.addAll(getConfiguredRepositories());
+			if (dirStrings.remove(dir)) {
+				saveDirs(dirStrings);
+				return true;
+			}
+			return false;
+		}
+	}
+
+	private void saveDirs(Set<String> gitDirStrings) {
+		StringBuilder sb = new StringBuilder();
+		for (String gitDirString : gitDirStrings) {
+			sb.append(gitDirString);
+			sb.append(File.pathSeparatorChar);
+		}
+
+		prefs.put(PREFS_DIRECTORIES, sb.toString());
+		try {
+			prefs.flush();
+		} catch (BackingStoreException e) {
+			IStatus error = new Status(IStatus.ERROR, Activator.getPluginId(),
+					e.getMessage(), e);
+			Activator.getDefault().getLog().log(error);
+		}
+	}
+
+	/**
+	 * Does the collection of repository returned by
+	 * {@link #getConfiguredRepositories()} contain the given repository?
+	 *
+	 * @param repository
+	 * @return true if contains repository, false otherwise
+	 */
+	public boolean contains(final Repository repository) {
+		return contains(getPath(repository.getDirectory()));
+	}
+
+	/**
+	 * Does the collection of repository returned by
+	 * {@link #getConfiguredRepositories()} contain the given repository
+	 * directory?
+	 *
+	 * @param repositoryDir
+	 * @return true if contains repository directory, false otherwise
+	 */
+	public boolean contains(final String repositoryDir) {
+		return getRepositories().contains(repositoryDir);
+	}
+
+	/**
+	 * Get short branch text for given repository
+	 *
+	 * @param repository
+	 * @return short branch text
+	 * @throws IOException
+	 */
+	public String getShortBranch(Repository repository) throws IOException {
+		Ref head = repository.getRef(Constants.HEAD);
+		if (head == null || head.getObjectId() == null)
+			return CoreText.RepositoryUtil_noHead;
+
+		if (head.isSymbolic())
+			return repository.getBranch();
+
+		String id = head.getObjectId().name();
+		String ref = mapCommitToRef(repository, id, false);
+		if (ref != null)
+			return Repository.shortenRefName(ref) + ' ' + id.substring(0, 7);
+		else
+			return id.substring(0, 7);
+	}
+
+	/**
+	 * Resolve HEAD and parse the commit. Returns null if HEAD does not exist or
+	 * could not be parsed.
+	 * <p>
+	 * Only use this if you don't already have to work with a RevWalk.
+	 *
+	 * @param repository
+	 * @return the commit or null if HEAD does not exist or could not be parsed.
+	 * @since 2.2
+	 */
+	public RevCommit parseHeadCommit(Repository repository) {
+		RevWalk walk = null;
+		try {
+			Ref head = repository.getRef(Constants.HEAD);
+			if (head == null || head.getObjectId() == null)
+				return null;
+
+			walk = new RevWalk(repository);
+			RevCommit commit = walk.parseCommit(head.getObjectId());
+			return commit;
+		} catch (IOException e) {
+			return null;
+		} finally {
+			if (walk != null)
+				walk.release();
+		}
+	}
+
+	/**
+	 * Checks if resource with given path is to be ignored.
+	 *
+	 * @param path
+	 *            Path to be checked
+	 * @return true if the path matches an ignore rule or no repository mapping
+	 *         could be found, false otherwise
+	 * @throws IOException
+	 * @since 2.3
+	 */
+	public static boolean isIgnored(IPath path) throws IOException {
+		RepositoryMapping mapping = RepositoryMapping.getMapping(path);
+		if (mapping == null)
+			return true; // Linked resources may not be mapped
+		Repository repository = mapping.getRepository();
+		String repoRelativePath = mapping.getRepoRelativePath(path);
+		TreeWalk walk = new TreeWalk(repository);
+		try {
+			walk.addTree(new FileTreeIterator(repository));
+			walk.setFilter(PathFilter.create(repoRelativePath));
+			while (walk.next()) {
+				WorkingTreeIterator workingTreeIterator = walk.getTree(0,
+						WorkingTreeIterator.class);
+				if (walk.getPathString().equals(repoRelativePath))
+					return workingTreeIterator.isEntryIgnored();
+				if (workingTreeIterator.getEntryFileMode()
+						.equals(FileMode.TREE))
+					walk.enterSubtree();
+			}
+		} finally {
+			walk.release();
+		}
+		return false;
+	}
+
+	/**
+	 * Get the fast-forward setting for current branch on the given repository.
+	 *
+	 * @param repository
+	 *            the repository to check
+	 * @return the fast-forward mode for the current branch
+	 * @since 2.4
+	 */
+	public FastForwardMode getFastForwardMode(Repository repository) {
+		FastForwardMode ffmode = FastForwardMode.valueOf(repository.getConfig()
+				.getEnum(ConfigConstants.CONFIG_KEY_MERGE, null,
+						ConfigConstants.CONFIG_KEY_FF,
+						FastForwardMode.Merge.TRUE));
+		ffmode = repository.getConfig().getEnum(
+				ConfigConstants.CONFIG_BRANCH_SECTION,
+				getCurrentBranch(repository),
+				ConfigConstants.CONFIG_KEY_MERGEOPTIONS, ffmode);
+		return ffmode;
+	}
+
+	private String getCurrentBranch(Repository repository) {
+		try {
+			return repository.getBranch();
+		} catch (IOException e) {
+			return null;
+		}
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/RevUtils.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/RevUtils.java
new file mode 100644
index 0000000..9e27ab4
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/RevUtils.java
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
+ * Copyright (C) 2012, Robin Stocker <robin@nibor.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal;
+
+import java.io.IOException;
+import java.util.Collection;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jgit.lib.AnyObjectId;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.revwalk.filter.RevFilter;
+
+/**
+ * Utility class for obtaining Rev object instances.
+ */
+public class RevUtils {
+
+	private RevUtils() {
+		// non instanciable utility class
+	}
+
+	/**
+	 * Finds and returns instance of common ancestor commit for given to
+	 * commit's
+	 *
+	 * @param repo repository in which common ancestor should be searched, cannot be null
+	 * @param commit1 left commit id, cannot be null
+	 * @param commit2 right commit id, cannot be null
+	 * @return common ancestor for commit1 and commit2 parameters
+	 * @throws IOException
+	 */
+	public static RevCommit getCommonAncestor(Repository repo,
+			AnyObjectId commit1, AnyObjectId commit2) throws IOException {
+		Assert.isNotNull(repo);
+		Assert.isNotNull(commit1);
+		Assert.isNotNull(commit2);
+
+		RevWalk rw = new RevWalk(repo);
+		try {
+			rw.setRetainBody(false);
+			rw.setRevFilter(RevFilter.MERGE_BASE);
+
+			RevCommit srcRev = rw.lookupCommit(commit1);
+			RevCommit dstRev = rw.lookupCommit(commit2);
+
+			rw.markStart(dstRev);
+			rw.markStart(srcRev);
+
+			RevCommit result = rw.next();
+			if (result != null) {
+				rw.parseBody(result);
+				return result;
+			} else {
+				return null;
+			}
+		} finally {
+			rw.release();
+		}
+	}
+
+	/**
+	 * Check if commit is contained in any of the passed refs.
+	 *
+	 * @param repo
+	 *            the repo the commit is in
+	 * @param commitId
+	 *            the commit ID to search for
+	 * @param refs
+	 *            the refs to check
+	 * @return true if the commit is contained, false otherwise
+	 * @throws IOException
+	 */
+	public static boolean isContainedInAnyRef(Repository repo,
+			ObjectId commitId, Collection<Ref> refs) throws IOException {
+		// It's likely that we don't have to walk commits at all, so
+		// check refs directly first.
+		for (Ref ref : refs)
+			if (commitId.equals(ref.getObjectId()))
+				return true;
+
+		RevWalk walk = new RevWalk(repo);
+		try {
+			RevCommit commit = walk.parseCommit(commitId);
+			for (Ref ref : refs) {
+				RevCommit refCommit = walk.parseCommit(ref.getObjectId());
+				boolean contained = walk.isMergedInto(commit, refCommit);
+				if (contained)
+					return true;
+			}
+		} finally {
+			walk.dispose();
+		}
+		return false;
+	}
+
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/coretext.properties b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/coretext.properties
new file mode 100644
index 0000000..19d3d94
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/coretext.properties
@@ -0,0 +1,176 @@
+###############################################################################
+# Copyright (c) 2006, 2012 Shawn Pearce and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#    Shawn Pearce - initial implementation
+#    Daniel Megert <daniel_megert@ch.ibm.com> - Escaped single quotes where needed
+###############################################################################
+
+CherryPickOperation_cherryPicking=Running cherry-pick on commit {0}
+CommitFileRevision_pathNotIn=Path {1} not in commit {0}.
+CommitFileRevision_errorLookingUpPath=IO error looking up path {1} in {0}.
+ConfigureFetchAfterCloneTask_couldNotFetch=Could not fetch with refSpec {0}
+ConnectProviderOperation_connecting=Connecting Git team provider.
+ConnectProviderOperation_ConnectingProject=Connecting project {0}
+
+DeleteBranchOperation_TaskName=Deleting branch {0}
+DeleteTagOperation_exceptionMessage=Exception deleting tag ''{0}''
+DiffHeaderFormat_Email=email
+DiffHeaderFormat_None=None
+DiffHeaderFormat_Oneline=oneline
+DiffHeaderFormat_Workspace=Workspace
+DiscardChangesOperation_discardFailed=Discarding changes of {0} failed
+DiscardChangesOperation_discardFailedSeeLog=Discarding changes failed. See log for details
+DiscardChangesOperation_discardingChanges=Discarding changes
+DiscardChangesOperation_refreshFailed=Refreshing resources failed
+DeleteResourcesOperation_deletingResources=Deleting resources
+DeleteResourcesOperation_deleteFailed=Deleting resource {0} failed.
+DeleteResourcesOperation_deleteFailedSeeLog=Deleting resources failed. See log for details
+DisconnectProviderOperation_disconnecting=Disconnecting Git team provider.
+
+Activator_autoIgnoreDerivedResources=Auto-ignore derived resources
+Activator_AutoShareJobName=Auto share git projects
+Activator_AutoSharingFailed=Auto sharing project with git failed
+Activator_ignoreResourceFailed=Ignoring {0} failed
+Activator_ReconfigureWindowCacheError=Exception when reconfiguring window cache from configuration, default configuration will be used
+
+AssumeUnchangedOperation_adding=Marking resources unchanged
+AssumeUnchangedOperation_writingIndex=Writing index for {0}
+BlobStorage_blobNotFound=Git blob {0} with path {1} not found
+BlobStorage_errorReadingBlob=IO error reading Git blob {0} with path {1}
+
+CommitOperation_errorCommittingChanges=Committing changes
+CommitOperation_errorPreparingTrees=Preparing trees
+CommitOperation_errorWritingTrees=Writing trees
+CommitOperation_failedToUpdate=Failed to update {0} to commit {1}.
+CommitOperation_PerformingCommit=Performing commit
+CommitOperation_couldNotFindRepositoryMapping=Could not find RepositoryMapping for {0}
+CommitOperation_errorParsingPersonIdent=The person ident ''{0}'' could not be parsed.
+
+UntrackOperation_adding=Untracking (removing) resources.
+UntrackOperation_failed=Failed to untrack resource.
+UntrackOperation_writingIndex=Writing index for {0}
+
+GitFileHistory_errorParsingHistory=Error parsing history for {0}.
+GitFileHistory_gitNotAttached=Git not attached to project {0}.
+GitFileHistory_invalidHeadRevision=Invalid HEAD revision for project {0}.
+GitFileHistory_noHeadRevisionAvailable=No HEAD revision available from Git for project {0}.
+GitProjectData_mappedResourceGone=Git mapped resource no longer exists in Eclipse: ''{0}''
+GitProjectData_failedFindingRepoMapping=Failed finding RepositoryMapping
+GitProjectData_failedToCacheRepoMapping=Failed to cache RepositoryMapping
+GitProjectData_FailedToMarkTeamPrivate=Failed to mark {0} as team private
+GitProjectData_missing=Git team provider configuration has gone missing.
+GitProjectData_saveFailed=Saving Git team provider data to {0} failed.
+
+RepositoryFinder_finding=Searching for associated repositories.
+RepositoryUtil_noHead=NO-HEAD
+ResetOperation_cantUpdate=Can''t update {0}
+ResetOperation_lookingUpCommit=looking up commit {0}
+ResetOperation_lookingUpRef=looking up ref {0}
+ResetOperation_mappingTreeForCommit=mapping tree for commit
+ResetOperation_performingReset=Performing {0} reset to {1}
+ResetOperation_readingIndex=Reading index
+ResetOperation_resetMergeFailed=Resetting merge mode failed
+ResetOperation_resetCherryPickFailed=Resetting cherry pick mode failed
+ResetOperation_updatingFailed=Updating {0} failed
+
+MergeOperation_CheckoutConflict=Checkout conflict: Your local changes to {0}\nwould be overwritten by merge.  Aborting. Commit your changes or stash them before you can merge.
+MergeOperation_InternalError=An internal error occurred
+MergeOperation_MergeFailedNoHead=Merge failed: Reference to HEAD does not exist
+MergeOperation_MergeFailedRefUpdate=Merge failed: Another process is accessing the ref
+MergeOperation_ProgressMerge=Merge {0}
+MoveDeleteHook_cannotModifyFolder=Folder contains an active Git repository.\n\
+The folder cannot be moved, renamed or deleted until the team provider is disconnected.
+
+MoveDeleteHook_operationError=Error updating cache during move/delete.\n\
+The resource cannot be moved, renamed or deleted due to an internal error.
+MoveDeleteHook_unmergedFileError=Move of file was canceled because it has conflicts.\n\
+Resolve the conflicts first and then move the file.
+MoveDeleteHook_unmergedFileInFolderError=Move of folder was canceled because it contains files with conflicts.\n\
+Resolve the conflicts first and then move the folder.
+
+Error_CanonicalFile=Unable to determine a canonical file path.
+
+ProjectReference_InvalidTokensCount={0} tokens expected in project reference but {1} had been found: {2}
+GitProjectSetCapability_CloneToExistingDirectory=Destination directory {0} already exists and doesn''t contain the expected Git repository. Won''t clone {1} from {2} to prevent data loss.
+GitProjectSetCapability_ExportCouldNotGetBranch=Could not get current branch from repository of project {0}.
+GitProjectSetCapability_ExportNoRemote=No remote URL configured for current branch in repository of project {0}.
+
+CloneOperation_checkingOutFiles=Checking out files
+CloneOperation_failed_cleanup=Clone operation failed, with failed cleanup: {0}. Manual cleanup may be required.
+CloneOperation_initializingRepository=Initializing local repository
+CloneOperation_title=Cloning from {0}
+CloneOperation_writingIndex=Writing index
+CreateLocalBranchOperation_CreatingBranchMessage=Creating branch {0}
+CreatePatchOperation_repoRequired=A repository is required  to create a patch
+CreatePatchOperation_cannotCreatePatchForMergeCommit=Cannot create patch for merge commit
+CreatePatchOperation_cannotCreatePatchForFirstCommit=Cannot create patch for first commit
+CreatePatchOperation_couldNotFindProject=Could not find project for {0} in repository {1}
+CreatePatchOperation_patchFileCouldNotBeWritten=Patch file could not be written
+IndexDiffCacheEntry_errorCalculatingIndexDelta=Failed to load index for repository {0}
+IndexDiffCacheEntry_refreshingProjects=Refreshing projects of repository {0}
+IndexDiffCacheEntry_reindexing=Re-indexing repository {0}
+IndexFileRevision_errorLookingUpPath=IO error looking up path {0} in index.
+IndexFileRevision_indexEntryNotFound=Git index entry for path {1} not found
+
+ListRemoteOperation_title=Getting remote branches information
+
+ProjectUtil_refreshingProjects=Refreshing projects
+ProjectUtil_refreshing=Refreshing
+ProjectUtil_taskCheckingDirectory=Checking: {0}
+PullOperation_DetachedHeadMessage=No local branch is currently checked out
+PullOperation_PullNotConfiguredMessage=The current branch is not configured for pull
+PullOperation_TaskName=Pulling {0} repositories
+PushOperation_InternalExceptionOccurredMessage=An internal Exception occurred during push: {0}
+PushOperation_ExceptionOccurredDuringPushOnUriMessage=An exception occurred during push on URI {0}: {1}
+PushOperation_resultCancelled=Operation was cancelled.
+PushOperation_taskNameDryRun=Trying pushing to remote repositories
+PushOperation_taskNameNormalRun=Pushing to remote repositories
+
+AddToIndexOperation_failed=Failed to add resource to index
+RemoveFromIndexOperation_removingFilesFromIndex=Removing files from index
+RemoveFromIndexOperation_failed=Failed to remove resource from index
+
+BranchOperation_closingMissingProject=Closing project ''{0}''
+BranchOperation_performingBranch=Switching to {0}
+TagOperation_performingTagging=Making tag {0}
+TagOperation_taggingFailure=Tag {0} creation failed (cause: {1})
+TagOperation_objectIdNotFound=Could not find object Id associated with tag {0} (cause: {1})
+
+GitFolderResourceVariant_fetchingMembers=Fetching members of {0}
+
+GitResourceVariantTree_couldNotFindResourceVariant=Could not find variant for resource: {0}
+GitResourceVariantTree_couldNotFetchMembers=Could not fetch members of {0}
+GitResourceVariantTree_fetchingVariant=Fetching variant for: {0}
+
+GitBranchResourceVariantTreeSubscriber_gitRepository=Git without local changes
+OperationAlreadyExecuted=Operation has already been executed and can not be executed again
+OperationNotYetExecuted=Operation has not yet been executed and can not return a result
+RemoteRefUpdateCantBeReused=The RemoteRefUpdate instance can not be re-used
+RenameBranchOperation_TaskName=Renaming branch {0} to {1}
+RevertCommitOperation_reverting=Reverting commit {0}
+
+IgnoreOperation_error=Unable to ignore resources
+IgnoreOperation_parentOutsideRepo=Can not add to gitignore. The parent of {0} is outside the Git repository {1}
+IgnoreOperation_creatingFailed=creating {0} failed
+IgnoreOperation_taskName=Adding resources to gitignore
+IgnoreOperation_updatingFailed=updating {0} failed
+
+GitSubscriberMergeContext_FailedUpdateRevs=Failed to update revisions
+GitSubscriberMergeContext_FailedRefreshSyncView=Failed to refresh synchronize view
+
+GitProjectData_repositoryChangedJobName=Git repository changed job
+GitProjectData_repositoryChangedTaskName=Git repository changed
+
+GitResourceVariantTreeSubscriber_fetchTaskName=Fetching data from git repositories
+
+GitSyncObjectCache_noData=Cache doesn''t contain data for key: {0}
+
+GitRemoteFolder_fetchingMembers=Fetching members of {0}
+
+GitURI_InvalidSCMURL=Invalid SCM URL {0}
+GitURI_InvalidURI=Invalid uri {0}: {1}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/indexdiff/GitResourceDeltaVisitor.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/indexdiff/GitResourceDeltaVisitor.java
index 8c9db92..575f48e 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/indexdiff/GitResourceDeltaVisitor.java
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/indexdiff/GitResourceDeltaVisitor.java
@@ -22,7 +22,7 @@
 import org.eclipse.core.resources.IResourceDelta;
 import org.eclipse.core.resources.IResourceDeltaVisitor;
 import org.eclipse.core.runtime.CoreException;
-import org.eclipse.egit.core.project.RepositoryMapping;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
 import org.eclipse.jgit.lib.Repository;
 
 /**
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/indexdiff/IndexDiffCache.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/indexdiff/IndexDiffCache.java
index c7f3671..58e598e 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/indexdiff/IndexDiffCache.java
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/indexdiff/IndexDiffCache.java
@@ -14,8 +14,8 @@
 import java.util.Set;
 
 import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.JobFamilies;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.JobFamilies;
 import org.eclipse.jgit.lib.IndexDiff;
 import org.eclipse.jgit.lib.Repository;
 
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/indexdiff/IndexDiffCacheEntry.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/indexdiff/IndexDiffCacheEntry.java
index 37ba6ec..ec31648 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/indexdiff/IndexDiffCacheEntry.java
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/indexdiff/IndexDiffCacheEntry.java
@@ -33,11 +33,11 @@
 import org.eclipse.core.runtime.OperationCanceledException;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.CoreText;
-import org.eclipse.egit.core.EclipseGitProgressTransformer;
-import org.eclipse.egit.core.IteratorService;
-import org.eclipse.egit.core.JobFamilies;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.CoreText;
+import org.eclipse.egit.core.internal.EclipseGitProgressTransformer;
+import org.eclipse.egit.core.internal.IteratorService;
+import org.eclipse.egit.core.internal.JobFamilies;
 import org.eclipse.egit.core.internal.trace.GitTraceLocation;
 import org.eclipse.egit.core.internal.util.ProjectUtil;
 import org.eclipse.jgit.dircache.DirCache;
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/job/JobUtil.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/job/JobUtil.java
index 305a13e..b85a8fa 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/job/JobUtil.java
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/job/JobUtil.java
@@ -14,7 +14,7 @@
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.jobs.IJobChangeListener;
 import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.egit.core.op.IEGitOperation;
+import org.eclipse.egit.core.internal.op.IEGitOperation;
 
 /**
  * Utility class for scheduling jobs
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/job/RuleUtil.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/job/RuleUtil.java
index a2624b3..d252288 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/job/RuleUtil.java
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/job/RuleUtil.java
@@ -24,8 +24,8 @@
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.jobs.ISchedulingRule;
 import org.eclipse.core.runtime.jobs.MultiRule;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
 import org.eclipse.egit.core.internal.util.ResourceUtil;
-import org.eclipse.egit.core.project.RepositoryMapping;
 import org.eclipse.jgit.lib.Repository;
 
 /**
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/AddToIndexOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/AddToIndexOperation.java
new file mode 100644
index 0000000..0b79d88
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/AddToIndexOperation.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Jens Baumgart <jens.baumgart@sap.com>
+ * Copyright (C) 2010, Stefan Lay <stefan.lay@sap.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.AdaptableFileTreeIterator;
+import org.eclipse.egit.core.internal.CoreText;
+import org.eclipse.egit.core.internal.job.RuleUtil;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.jgit.api.AddCommand;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.lib.Repository;
+
+/**
+ */
+public class AddToIndexOperation implements IEGitOperation {
+	private final Collection<? extends IResource> rsrcList;
+
+	/**
+	 * Create a new operation to add files to the Git index
+	 *
+	 * @param rsrcs
+	 *            collection of {@link IResource}s which should be added to the
+	 *            relevant Git repositories.
+	 */
+	public AddToIndexOperation(final Collection<? extends IResource> rsrcs) {
+		rsrcList = rsrcs;
+	}
+
+	/**
+	 * Create a new operation to add files to the Git index
+	 *
+	 * @param resources
+	 *            array of {@link IResource}s which should be added to the
+	 *            relevant Git repositories.
+	 */
+	public AddToIndexOperation(IResource[] resources) {
+		rsrcList = Arrays.asList(resources);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.egit.core.op.IEGitOperation#execute(org.eclipse.core.runtime.IProgressMonitor)
+	 */
+	public void execute(IProgressMonitor m) throws CoreException {
+		IProgressMonitor monitor;
+		if (m == null)
+			monitor = new NullProgressMonitor();
+		else
+			monitor = m;
+
+		Map<RepositoryMapping, AddCommand> addCommands = new HashMap<RepositoryMapping, AddCommand>();
+		try {
+			for (IResource obj : rsrcList) {
+				addToCommand(obj, addCommands);
+				monitor.worked(200);
+			}
+
+			for (AddCommand command : addCommands.values()) {
+				command.call();
+			}
+		} catch (RuntimeException e) {
+			throw new CoreException(Activator.error(CoreText.AddToIndexOperation_failed, e));
+		} catch (GitAPIException e) {
+			throw new CoreException(Activator.error(CoreText.AddToIndexOperation_failed, e));
+		} finally {
+			for (final RepositoryMapping rm : addCommands.keySet())
+				rm.fireRepositoryChanged();
+			monitor.done();
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.egit.core.op.IEGitOperation#getSchedulingRule()
+	 */
+	public ISchedulingRule getSchedulingRule() {
+		return RuleUtil.getRuleForRepositories(rsrcList.toArray(new IResource[rsrcList.size()]));
+	}
+
+	private void addToCommand(IResource resource, Map<RepositoryMapping, AddCommand> addCommands) {
+		IProject project = resource.getProject();
+		RepositoryMapping map = RepositoryMapping.getMapping(project);
+		AddCommand command = addCommands.get(map);
+		if (command == null) {
+			Repository repo = map.getRepository();
+			Git git = new Git(repo);
+			AdaptableFileTreeIterator it = new AdaptableFileTreeIterator(repo,
+					resource.getWorkspace().getRoot());
+			command = git.add().setWorkingTreeIterator(it);
+			addCommands.put(map, command);
+		}
+		String filepattern = map.getRepoRelativePath(resource);
+		if ("".equals(filepattern)) //$NON-NLS-1$
+			filepattern = "."; //$NON-NLS-1$
+		command.addFilepattern(filepattern);
+	}
+
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/AssumeUnchangedOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/AssumeUnchangedOperation.java
new file mode 100644
index 0000000..a32d954
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/AssumeUnchangedOperation.java
@@ -0,0 +1,150 @@
+/*******************************************************************************
+ * Copyright (C) 2007, Robin Rosenberg <robin.rosenberg@dewire.com>
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
+ * Copyright (C) 2008, Google Inc.
+ * Copyright (C) 2010, Matthias Sohn <matthias.sohn@sap.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.IdentityHashMap;
+import java.util.Map;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.CoreText;
+import org.eclipse.egit.core.internal.job.RuleUtil;
+import org.eclipse.egit.core.internal.project.GitProjectData;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.jgit.dircache.DirCache;
+import org.eclipse.jgit.dircache.DirCacheEntry;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Tell JGit to ignore changes in selected files
+ */
+public class AssumeUnchangedOperation implements IEGitOperation {
+	private final Collection<? extends IResource> rsrcList;
+
+	private final IdentityHashMap<Repository, DirCache> caches;
+
+	private final IdentityHashMap<RepositoryMapping, Object> mappings;
+
+	private boolean assumeUnchanged;
+
+	/**
+	 * Create a new operation to ignore changes in tracked files
+	 *
+	 * @param rsrcs
+	 *            collection of {@link IResource}s which should be ignored when
+	 *            looking for changes or committing.
+	 * @param assumeUnchanged
+	 *            {@code true} to set the assume-valid flag in the git index
+	 *            entry, {@code false} to unset the assume-valid flag in the git
+	 *            index entry
+	 */
+	public AssumeUnchangedOperation(
+			final Collection<? extends IResource> rsrcs, boolean assumeUnchanged) {
+		rsrcList = rsrcs;
+		caches = new IdentityHashMap<Repository, DirCache>();
+		mappings = new IdentityHashMap<RepositoryMapping, Object>();
+		this.assumeUnchanged = assumeUnchanged;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.egit.core.op.IEGitOperation#execute(org.eclipse.core.runtime.IProgressMonitor)
+	 */
+	public void execute(IProgressMonitor m) throws CoreException {
+		IProgressMonitor monitor;
+		if (m == null)
+			monitor = new NullProgressMonitor();
+		else
+			monitor = m;
+
+		caches.clear();
+		mappings.clear();
+
+		monitor.beginTask(CoreText.AssumeUnchangedOperation_adding,
+				rsrcList.size() * 200);
+		try {
+			for (IResource resource : rsrcList) {
+				assumeValid(resource);
+				monitor.worked(200);
+			}
+
+			for (Map.Entry<Repository, DirCache> e : caches.entrySet()) {
+				final Repository db = e.getKey();
+				final DirCache editor = e.getValue();
+				monitor.setTaskName(NLS.bind(
+						CoreText.AssumeUnchangedOperation_writingIndex, db
+								.getDirectory()));
+				editor.write();
+				editor.commit();
+			}
+		} catch (RuntimeException e) {
+			throw new CoreException(Activator.error(CoreText.UntrackOperation_failed, e));
+		} catch (IOException e) {
+			throw new CoreException(Activator.error(CoreText.UntrackOperation_failed, e));
+		} finally {
+			for (final RepositoryMapping rm : mappings.keySet())
+				rm.fireRepositoryChanged();
+			for (DirCache cache:caches.values())
+				cache.unlock();
+			caches.clear();
+			mappings.clear();
+			monitor.done();
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.egit.core.op.IEGitOperation#getSchedulingRule()
+	 */
+	public ISchedulingRule getSchedulingRule() {
+		return RuleUtil.getRuleForRepositories(rsrcList.toArray(new IResource[rsrcList.size()]));
+	}
+
+	private void assumeValid(final IResource resource) throws CoreException {
+		final IProject proj = resource.getProject();
+		final GitProjectData pd = GitProjectData.get(proj);
+		if (pd == null)
+			return;
+		final RepositoryMapping rm = pd.getRepositoryMapping(resource);
+		if (rm == null)
+			return;
+		final Repository db = rm.getRepository();
+
+		DirCache cache = caches.get(db);
+		if (cache == null) {
+			try {
+				cache = db.lockDirCache();
+			} catch (IOException err) {
+				throw new CoreException(Activator.error(CoreText.UntrackOperation_failed, err));
+			}
+			caches.put(db, cache);
+			mappings.put(rm, rm);
+		}
+
+		final String path = rm.getRepoRelativePath(resource);
+		if (resource instanceof IContainer) {
+			for (final DirCacheEntry ent : cache.getEntriesWithin(path))
+				ent.setAssumeValid(assumeUnchanged);
+		} else {
+			final DirCacheEntry ent = cache.getEntry(path);
+			if (ent != null)
+				ent.setAssumeValid(assumeUnchanged);
+		}
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/BaseOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/BaseOperation.java
new file mode 100644
index 0000000..87556d6
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/BaseOperation.java
@@ -0,0 +1,82 @@
+/******************************************************************************
+ *  Copyright (c) 2012 GitHub Inc.
+ *  All rights reserved. This program and the accompanying materials
+ *  are made available under the terms of the Eclipse Public License v1.0
+ *  which accompanies this distribution, and is available at
+ *  http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *    Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *****************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jgit.lib.Repository;
+
+/**
+ * Base operation that supports adding pre/post tasks
+ */
+abstract class BaseOperation implements IEGitOperation {
+
+	protected final Repository repository;
+
+	protected Collection<PreExecuteTask> preTasks;
+
+	protected Collection<PostExecuteTask> postTasks;
+
+	BaseOperation(final Repository repository) {
+		this.repository = repository;
+	}
+
+	/**
+	 * Invoke all pre-execute tasks
+	 *
+	 * @param monitor
+	 * @throws CoreException
+	 */
+	protected void preExecute(IProgressMonitor monitor) throws CoreException {
+		synchronized (this) {
+			if (preTasks != null)
+				for (PreExecuteTask task : preTasks)
+					task.preExecute(repository, monitor);
+		}
+	}
+
+	/**
+	 * Invoke all post-execute tasks
+	 *
+	 * @param monitor
+	 * @throws CoreException
+	 */
+	protected void postExecute(IProgressMonitor monitor) throws CoreException {
+		synchronized (this) {
+			if (postTasks != null)
+				for (PostExecuteTask task : postTasks)
+					task.postExecute(repository, monitor);
+		}
+	}
+
+	/**
+	 * @param task
+	 *            to be performed before execution
+	 */
+	public synchronized void addPreExecuteTask(final PreExecuteTask task) {
+		if (preTasks == null)
+			preTasks = new ArrayList<PreExecuteTask>();
+		preTasks.add(task);
+	}
+
+	/**
+	 * @param task
+	 *            to be performed after execution
+	 */
+	public synchronized void addPostExecuteTask(PostExecuteTask task) {
+		if (postTasks == null)
+			postTasks = new ArrayList<PostExecuteTask>();
+		postTasks.add(task);
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/BranchOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/BranchOperation.java
new file mode 100644
index 0000000..3eba801
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/BranchOperation.java
@@ -0,0 +1,266 @@
+/*******************************************************************************
+ * Copyright (C) 2007, Dave Watson <dwatson@mimvista.com>
+ * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
+ * Copyright (C) 2006, Shawn O. Pearce <spearce@spearce.org>
+ * Copyright (C) 2010, Jens Baumgart <jens.baumgart@sap.com>
+ * Copyright (C) 2010, 2011, Mathias Kinzler <mathias.kinzler@sap.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import java.io.File;
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.CoreText;
+import org.eclipse.egit.core.internal.util.ProjectUtil;
+import org.eclipse.jgit.api.CheckoutCommand;
+import org.eclipse.jgit.api.CheckoutResult;
+import org.eclipse.jgit.api.CheckoutResult.Status;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.CheckoutConflictException;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.api.errors.JGitInternalException;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.Repository;
+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.filter.AndTreeFilter;
+import org.eclipse.jgit.treewalk.filter.PathSuffixFilter;
+import org.eclipse.jgit.treewalk.filter.TreeFilter;
+import org.eclipse.jgit.util.FileUtils;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * This class implements checkouts of a specific revision. A check is made that
+ * this can be done without data loss.
+ */
+public class BranchOperation extends BaseOperation {
+
+	private final String target;
+
+	private CheckoutResult result;
+
+	private boolean delete;
+
+	/**
+	 * Construct a {@link BranchOperation} object for a {@link Ref}.
+	 *
+	 * @param repository
+	 * @param target
+	 *            a {@link Ref} name or {@link RevCommit} id
+	 */
+	public BranchOperation(Repository repository, String target) {
+		this(repository, target, true);
+	}
+
+	/**
+	 * Construct a {@link BranchOperation} object for a {@link Ref}.
+	 *
+	 * @param repository
+	 * @param target
+	 *            a {@link Ref} name or {@link RevCommit} id
+	 * @param delete
+	 *            true to delete missing projects on new branch, false to close
+	 *            them
+	 */
+	public BranchOperation(Repository repository, String target, boolean delete) {
+		super(repository);
+		this.target = target;
+		this.delete = delete;
+	}
+
+	public void execute(IProgressMonitor m) throws CoreException {
+		IProgressMonitor monitor;
+		if (m == null)
+			monitor = new NullProgressMonitor();
+		else
+			monitor = m;
+
+		IWorkspaceRunnable action = new IWorkspaceRunnable() {
+
+			public void run(IProgressMonitor pm) throws CoreException {
+				preExecute(pm);
+
+				IProject[] missing = getMissingProjects(target, ProjectUtil
+						.getValidOpenProjects(repository));
+
+				pm.beginTask(NLS.bind(
+						CoreText.BranchOperation_performingBranch, target),
+						missing.length > 0 ? 3 : 2);
+
+				if (missing.length > 0) {
+					SubProgressMonitor closeMonitor = new SubProgressMonitor(
+							pm, 1);
+					closeMonitor.beginTask("", missing.length); //$NON-NLS-1$
+					for (IProject project : missing) {
+						closeMonitor.subTask(MessageFormat.format(
+								CoreText.BranchOperation_closingMissingProject,
+								project.getName()));
+						project.close(closeMonitor);
+					}
+					closeMonitor.done();
+				}
+
+				CheckoutCommand co = new Git(repository).checkout();
+				co.setName(target);
+
+				try {
+					co.call();
+				} catch (CheckoutConflictException e) {
+					return;
+				} catch (JGitInternalException e) {
+					throw new CoreException(Activator.error(e.getMessage(), e));
+				} catch (GitAPIException e) {
+					throw new CoreException(Activator.error(e.getMessage(), e));
+				} finally {
+					BranchOperation.this.result = co.getResult();
+				}
+				if (result.getStatus() == Status.NONDELETED)
+					retryDelete(result.getUndeletedList());
+				pm.worked(1);
+
+				List<String> pathsToHandle = new ArrayList<String>();
+				pathsToHandle.addAll(co.getResult().getModifiedList());
+				pathsToHandle.addAll(co.getResult().getRemovedList());
+				pathsToHandle.addAll(co.getResult().getConflictList());
+				IProject[] refreshProjects = ProjectUtil
+						.getProjectsContaining(repository, pathsToHandle);
+				ProjectUtil.refreshValidProjects(refreshProjects, delete,
+						new SubProgressMonitor(pm, 1));
+				pm.worked(1);
+
+				postExecute(pm);
+
+				pm.done();
+			}
+		};
+		// lock workspace to protect working tree changes
+		ResourcesPlugin.getWorkspace().run(action, monitor);
+	}
+
+	public ISchedulingRule getSchedulingRule() {
+		return ResourcesPlugin.getWorkspace().getRoot();
+	}
+
+	/**
+	 * @return the result of the operation
+	 */
+	public CheckoutResult getResult() {
+		return result;
+	}
+
+	void retryDelete(List<String> pathList) {
+		// try to delete, but for a short time only
+		long startTime = System.currentTimeMillis();
+		for (String path : pathList) {
+			if (System.currentTimeMillis() - startTime > 1000)
+				break;
+			File fileToDelete = new File(repository.getWorkTree(), path);
+			if (fileToDelete.exists())
+				try {
+					// Only files should be passed here, thus
+					// we ignore attempt to delete submodules when
+					// we switch to a branch without a submodule
+					if (!fileToDelete.isFile())
+						FileUtils.delete(fileToDelete, FileUtils.RETRY);
+				} catch (IOException e) {
+					// ignore here
+				}
+		}
+	}
+
+	/**
+	 * Compute the current projects that will be missing after the given branch
+	 * is checked out
+	 *
+	 * @param branch
+	 * @param currentProjects
+	 * @return non-null but possibly empty array of missing projects
+	 */
+	private IProject[] getMissingProjects(String branch,
+			IProject[] currentProjects) {
+		if (delete || currentProjects.length == 0)
+			return new IProject[0];
+
+		ObjectId targetTreeId;
+		ObjectId currentTreeId;
+		try {
+			targetTreeId = repository.resolve(branch + "^{tree}"); //$NON-NLS-1$
+			currentTreeId = repository.resolve(Constants.HEAD + "^{tree}"); //$NON-NLS-1$
+		} catch (IOException e) {
+			return new IProject[0];
+		}
+		if (targetTreeId == null || currentTreeId == null)
+			return new IProject[0];
+
+		Map<File, IProject> locations = new HashMap<File, IProject>();
+		for (IProject project : currentProjects) {
+			IPath location = project.getLocation();
+			if (location == null)
+				continue;
+			location = location
+					.append(IProjectDescription.DESCRIPTION_FILE_NAME);
+			locations.put(location.toFile(), project);
+		}
+
+		List<IProject> toBeClosed = new ArrayList<IProject>();
+		File root = repository.getWorkTree();
+		TreeWalk walk = new TreeWalk(repository);
+		try {
+			walk.addTree(targetTreeId);
+			walk.addTree(currentTreeId);
+			walk.addTree(new FileTreeIterator(repository));
+			walk.setRecursive(true);
+			walk.setFilter(AndTreeFilter.create(PathSuffixFilter
+					.create(IProjectDescription.DESCRIPTION_FILE_NAME),
+					TreeFilter.ANY_DIFF));
+			while (walk.next()) {
+				AbstractTreeIterator targetIter = walk.getTree(0,
+						AbstractTreeIterator.class);
+				if (targetIter != null)
+					continue;
+
+				AbstractTreeIterator currentIter = walk.getTree(1,
+						AbstractTreeIterator.class);
+				AbstractTreeIterator workingIter = walk.getTree(2,
+						AbstractTreeIterator.class);
+				if (currentIter == null || workingIter == null)
+					continue;
+
+				IProject project = locations.get(new File(root, walk
+						.getPathString()));
+				if (project != null)
+					toBeClosed.add(project);
+			}
+		} catch (IOException e) {
+			return new IProject[0];
+		} finally {
+			walk.release();
+		}
+		return toBeClosed.toArray(new IProject[toBeClosed.size()]);
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/CherryPickOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/CherryPickOperation.java
new file mode 100644
index 0000000..da9278f
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/CherryPickOperation.java
@@ -0,0 +1,94 @@
+/******************************************************************************
+ *  Copyright (c) 2011 GitHub Inc.
+ *  All rights reserved. This program and the accompanying materials
+ *  are made available under the terms of the Eclipse Public License v1.0
+ *  which accompanies this distribution, and is available at
+ *  http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *    Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *****************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import java.text.MessageFormat;
+
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.egit.core.internal.CoreText;
+import org.eclipse.egit.core.internal.util.ProjectUtil;
+import org.eclipse.jgit.api.CherryPickCommand;
+import org.eclipse.jgit.api.CherryPickResult;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.team.core.TeamException;
+
+/**
+ * Cherry pick operation
+ */
+public class CherryPickOperation implements IEGitOperation {
+
+	private final Repository repo;
+
+	private final RevCommit commit;
+
+	private CherryPickResult result;
+
+	/**
+	 * Create cherry pick operation
+	 *
+	 * @param repository
+	 * @param commit
+	 */
+	public CherryPickOperation(Repository repository, RevCommit commit) {
+		this.repo = repository;
+		this.commit = commit;
+	}
+
+	/**
+	 * @return cherry pick result
+	 */
+	public CherryPickResult getResult() {
+		return result;
+	}
+
+	public void execute(IProgressMonitor m) throws CoreException {
+		IProgressMonitor monitor = m != null ? m : new NullProgressMonitor();
+		IWorkspaceRunnable action = new IWorkspaceRunnable() {
+
+			public void run(IProgressMonitor pm) throws CoreException {
+				pm.beginTask("", 2); //$NON-NLS-1$
+
+				pm.subTask(MessageFormat.format(
+						CoreText.CherryPickOperation_cherryPicking,
+						commit.name()));
+				CherryPickCommand command = new Git(repo).cherryPick().include(
+						commit.getId());
+				try {
+					result = command.call();
+				} catch (GitAPIException e) {
+					throw new TeamException(e.getLocalizedMessage(),
+							e.getCause());
+				}
+				pm.worked(1);
+
+				ProjectUtil.refreshValidProjects(
+						ProjectUtil.getValidOpenProjects(repo),
+						new SubProgressMonitor(pm, 1));
+
+				pm.done();
+			}
+		};
+		ResourcesPlugin.getWorkspace().run(action, monitor);
+	}
+
+	public ISchedulingRule getSchedulingRule() {
+		return ResourcesPlugin.getWorkspace().getRoot();
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/CloneOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/CloneOperation.java
new file mode 100644
index 0000000..cdf0d29
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/CloneOperation.java
@@ -0,0 +1,215 @@
+/*******************************************************************************
+ * Copyright (C) 2007, Dave Watson <dwatson@mimvista.com>
+ * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
+ * Copyright (C) 2008, Roger C. Soares <rogersoares@intelinet.com.br>
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
+ * Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.egit.core.internal.CoreText;
+import org.eclipse.egit.core.internal.EclipseGitProgressTransformer;
+import org.eclipse.jgit.api.CloneCommand;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.transport.CredentialsProvider;
+import org.eclipse.jgit.transport.URIish;
+import org.eclipse.jgit.util.FileUtils;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Clones a repository from a remote location to a local location.
+ */
+public class CloneOperation {
+	private final URIish uri;
+
+	private final boolean allSelected;
+
+	private boolean cloneSubmodules;
+
+	private final Collection<Ref> selectedBranches;
+
+	private final File workdir;
+
+	private final File gitdir;
+
+	private final String refName;
+
+	private final String remoteName;
+
+	private final int timeout;
+
+	private CredentialsProvider credentialsProvider;
+
+	private List<PostCloneTask> postCloneTasks;
+
+	/**
+	 * Create a new clone operation.
+	 *
+	 * @param uri
+	 *            remote we should fetch from.
+	 * @param allSelected
+	 *            true when all branches have to be fetched (indicates wildcard
+	 *            in created fetch refspec), false otherwise.
+	 * @param selectedBranches
+	 *            collection of branches to fetch. Ignored when allSelected is
+	 *            true.
+	 * @param workdir
+	 *            working directory to clone to. The directory may or may not
+	 *            already exist.
+	 * @param refName
+	 *            full name of ref to be checked out after clone, e.g.
+	 *            refs/heads/master, or null for no checkout
+	 * @param remoteName
+	 *            name of created remote config as source remote (typically
+	 *            named "origin").
+	 * @param timeout
+	 *            timeout in seconds
+	 */
+	public CloneOperation(final URIish uri, final boolean allSelected,
+			final Collection<Ref> selectedBranches, final File workdir,
+			final String refName, final String remoteName, int timeout) {
+		this.uri = uri;
+		this.allSelected = allSelected;
+		this.selectedBranches = selectedBranches;
+		this.workdir = workdir;
+		this.gitdir = new File(workdir, Constants.DOT_GIT);
+		this.refName = refName;
+		this.remoteName = remoteName;
+		this.timeout = timeout;
+	}
+
+	/**
+	 * Sets a credentials provider
+	 * @param credentialsProvider
+	 */
+	public void setCredentialsProvider(CredentialsProvider credentialsProvider) {
+		this.credentialsProvider = credentialsProvider;
+	}
+
+	/**
+	 * @param cloneSubmodules
+	 *            true to initialize and update submodules
+	 */
+	public void setCloneSubmodules(boolean cloneSubmodules) {
+		this.cloneSubmodules = cloneSubmodules;
+	}
+
+	/**
+	 * @param pm
+	 *            the monitor to be used for reporting progress and responding
+	 *            to cancellation. The monitor is never <code>null</code>
+	 * @throws InvocationTargetException
+	 * @throws InterruptedException
+	 */
+	public void run(final IProgressMonitor pm)
+			throws InvocationTargetException, InterruptedException {
+		final IProgressMonitor monitor;
+		if (pm == null)
+			monitor = new NullProgressMonitor();
+		else
+			monitor = pm;
+
+		EclipseGitProgressTransformer gitMonitor = new EclipseGitProgressTransformer(
+				monitor);
+		Repository repository = null;
+		try {
+			monitor.beginTask(NLS.bind(CoreText.CloneOperation_title, uri),
+					5000);
+			CloneCommand cloneRepository = Git.cloneRepository();
+			cloneRepository.setCredentialsProvider(credentialsProvider);
+			if (refName != null)
+				cloneRepository.setBranch(refName);
+			else
+				cloneRepository.setNoCheckout(true);
+			cloneRepository.setDirectory(workdir);
+			cloneRepository.setProgressMonitor(gitMonitor);
+			cloneRepository.setRemote(remoteName);
+			cloneRepository.setURI(uri.toString());
+			cloneRepository.setTimeout(timeout);
+			cloneRepository.setCloneAllBranches(allSelected);
+			cloneRepository.setCloneSubmodules(cloneSubmodules);
+			if (selectedBranches != null) {
+				List<String> branches = new ArrayList<String>();
+				for (Ref branch : selectedBranches)
+					branches.add(branch.getName());
+				cloneRepository.setBranchesToClone(branches);
+			}
+			Git git = cloneRepository.call();
+			repository = git.getRepository();
+			synchronized (this) {
+				if (postCloneTasks != null)
+					for (PostCloneTask task : postCloneTasks)
+						task.execute(git.getRepository(), monitor);
+			}
+		} catch (final Exception e) {
+			try {
+				if (repository != null)
+					repository.close();
+				FileUtils.delete(workdir, FileUtils.RECURSIVE);
+			} catch (IOException ioe) {
+				throw new InvocationTargetException(e, NLS.bind(
+						CoreText.CloneOperation_failed_cleanup,
+						ioe.getLocalizedMessage()));
+			}
+			if (monitor.isCanceled())
+				throw new InterruptedException();
+			else
+				throw new InvocationTargetException(e);
+		} finally {
+			monitor.done();
+			if (repository != null)
+				repository.close();
+		}
+	}
+
+	/**
+	 * @return The git directory which will contain the repository
+	 */
+	public File getGitDir() {
+		return gitdir;
+	}
+
+	/**
+	 * @param task to be performed after clone
+	 */
+	public synchronized void addPostCloneTask(PostCloneTask task) {
+		if (postCloneTasks == null)
+			postCloneTasks = new ArrayList<PostCloneTask>();
+		postCloneTasks.add(task);
+	}
+
+	/**
+	 * A task which can be added to be performed after clone
+	 */
+	public interface PostCloneTask  {
+
+		/**
+		 * Executes the task
+		 * @param repository the cloned git repository
+		 *
+		 * @param monitor
+		 *            a progress monitor, or <code>null</code> if progress reporting
+		 *            and cancellation are not desired
+		 * @throws CoreException
+		 */
+		void execute(Repository repository, IProgressMonitor monitor) throws CoreException;
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/CommitOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/CommitOperation.java
new file mode 100644
index 0000000..30ea87a
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/CommitOperation.java
@@ -0,0 +1,320 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2012, SAP AG and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Stefan Lay (SAP AG) - initial implementation
+ *    Jens Baumgart (SAP AG)
+ *    Robin Stocker (independent)
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.TimeZone;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.CoreText;
+import org.eclipse.egit.core.internal.RepositoryUtil;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.jgit.api.AddCommand;
+import org.eclipse.jgit.api.CommitCommand;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.api.errors.JGitInternalException;
+import org.eclipse.jgit.lib.PersonIdent;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.util.RawParseUtils;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.team.core.TeamException;
+
+/**
+ * This class implements the commit of a list of files.
+ */
+public class CommitOperation implements IEGitOperation {
+
+	Collection<String> commitFileList;
+
+	private boolean commitWorkingDirChanges = false;
+
+	private String author;
+
+	private String committer;
+
+	private String message;
+
+	private boolean amending = false;
+
+	private boolean commitAll = false;
+
+	private Repository repo;
+
+	Collection<String> notTracked;
+
+	private boolean createChangeId;
+
+	private boolean commitIndex;
+
+	RevCommit commit = null;
+
+	/**
+	 * @param filesToCommit
+	 *            a list of files which will be included in the commit
+	 * @param notTracked
+	 *            a list of all untracked files
+	 * @param author
+	 *            the author of the commit
+	 * @param committer
+	 *            the committer of the commit
+	 * @param message
+	 *            the commit message
+	 * @throws CoreException
+	 */
+	public CommitOperation(IFile[] filesToCommit, Collection<IFile> notTracked,
+			String author, String committer, String message) throws CoreException {
+		this.author = author;
+		this.committer = committer;
+		this.message = message;
+		if (filesToCommit != null && filesToCommit.length > 0)
+			setRepository(filesToCommit[0]);
+		if (filesToCommit != null)
+			commitFileList = buildFileList(Arrays.asList(filesToCommit));
+		if (notTracked != null)
+			this.notTracked = buildFileList(notTracked);
+	}
+
+	/**
+	 * @param repository
+	 * @param filesToCommit
+	 *            a list of files which will be included in the commit
+	 * @param notTracked
+	 *            a list of all untracked files
+	 * @param author
+	 *            the author of the commit
+	 * @param committer
+	 *            the committer of the commit
+	 * @param message
+	 *            the commit message
+	 * @throws CoreException
+	 */
+	public CommitOperation(Repository repository, Collection<String> filesToCommit, Collection<String> notTracked,
+			String author, String committer, String message) throws CoreException {
+		this.repo = repository;
+		this.author = author;
+		this.committer = committer;
+		this.message = message;
+		if (filesToCommit != null)
+			commitFileList = new HashSet<String>(filesToCommit);
+		if (notTracked != null)
+			this.notTracked = new HashSet<String>(notTracked);
+	}
+
+	/**
+	 * Constructs a CommitOperation that commits the index
+	 * @param repository
+	 * @param author
+	 * @param committer
+	 * @param message
+	 * @throws CoreException
+	 */
+	public CommitOperation(Repository repository, String author, String committer,
+			String message) throws CoreException {
+		this.repo = repository;
+		this.author = author;
+		this.committer = committer;
+		this.message = message;
+		this.commitIndex = true;
+	}
+
+
+	private void setRepository(IFile file) throws CoreException {
+		RepositoryMapping mapping = RepositoryMapping.getMapping(file);
+		if (mapping == null)
+			throw new CoreException(Activator.error(NLS.bind(
+					CoreText.CommitOperation_couldNotFindRepositoryMapping,
+					file), null));
+		repo = mapping.getRepository();
+	}
+
+	/**
+	 * @param repository
+	 */
+	public void setRepository(Repository repository) {
+		repo = repository;
+	}
+
+	private Collection<String> buildFileList(Collection<IFile> files) throws CoreException {
+		Collection<String> result = new HashSet<String>();
+		for (IFile file : files) {
+			RepositoryMapping mapping = RepositoryMapping.getMapping(file);
+			if (mapping == null)
+				throw new CoreException(Activator.error(NLS.bind(CoreText.CommitOperation_couldNotFindRepositoryMapping, file), null));
+			String repoRelativePath = mapping.getRepoRelativePath(file);
+			result.add(repoRelativePath);
+		}
+		return result;
+	}
+
+	public void execute(IProgressMonitor m) throws CoreException {
+		IProgressMonitor monitor;
+		if (m == null)
+			monitor = new NullProgressMonitor();
+		else
+			monitor = m;
+		IWorkspaceRunnable action = new IWorkspaceRunnable() {
+
+			public void run(IProgressMonitor actMonitor) throws CoreException {
+				if (commitAll)
+					commitAll();
+				else if (amending || commitFileList != null
+						&& commitFileList.size() > 0 || commitIndex) {
+					actMonitor.beginTask(
+							CoreText.CommitOperation_PerformingCommit,
+							20);
+					actMonitor.setTaskName(CoreText.CommitOperation_PerformingCommit);
+					addUntracked();
+					commit();
+					actMonitor.worked(10);
+				} else if (commitWorkingDirChanges) {
+					// TODO commit -a
+				} else {
+					// TODO commit
+				}
+			}
+
+		};
+		ResourcesPlugin.getWorkspace().run(action, monitor);
+	}
+
+	private void addUntracked() throws CoreException {
+		if (notTracked == null || notTracked.size() == 0)
+			return;
+		AddCommand addCommand = new Git(repo).add();
+		boolean fileAdded = false;
+		for (String path : notTracked)
+			if (commitFileList.contains(path)) {
+				addCommand.addFilepattern(path);
+				fileAdded = true;
+			}
+		if (fileAdded)
+			try {
+				addCommand.call();
+			} catch (Exception e) {
+				throw new CoreException(Activator.error(e.getMessage(), e));
+			}
+	}
+
+	public ISchedulingRule getSchedulingRule() {
+		return ResourcesPlugin.getWorkspace().getRoot();
+	}
+
+	private void commit() throws TeamException {
+		Git git = new Git(repo);
+		try {
+			CommitCommand commitCommand = git.commit();
+			setAuthorAndCommitter(commitCommand);
+			commitCommand.setAmend(amending)
+					.setMessage(message)
+					.setInsertChangeId(createChangeId);
+			if (!commitIndex)
+				for(String path:commitFileList)
+					commitCommand.setOnly(path);
+			commit = commitCommand.call();
+		} catch (Exception e) {
+			throw new TeamException(
+					CoreText.MergeOperation_InternalError, e);
+		}
+	}
+
+	/**
+	 *
+	 * @param amending
+	 */
+	public void setAmending(boolean amending) {
+		this.amending = amending;
+	}
+
+	/**
+	 *
+	 * @param commitAll
+	 */
+	public void setCommitAll(boolean commitAll) {
+		this.commitAll = commitAll;
+	}
+
+	/**
+	 * @param createChangeId
+	 *            <code>true</code> if a Change-Id should be inserted
+	 */
+	public void setComputeChangeId(boolean createChangeId) {
+		this.createChangeId = createChangeId;
+	}
+
+	/**
+	 * @return the newly created commit if committing was successful, null otherwise.
+	 */
+	public RevCommit getCommit() {
+		return commit;
+	}
+
+	// TODO: can the commit message be change by the user in case of a merge commit?
+	private void commitAll() throws TeamException {
+
+		Git git = new Git(repo);
+		try {
+			CommitCommand commitCommand = git.commit();
+			setAuthorAndCommitter(commitCommand);
+			commit = commitCommand.setAll(true).setMessage(message)
+					.setInsertChangeId(createChangeId).call();
+		} catch (JGitInternalException e) {
+			throw new TeamException(CoreText.MergeOperation_InternalError, e);
+		} catch (GitAPIException e) {
+			throw new TeamException(e.getLocalizedMessage(), e);
+		}
+	}
+
+	private void setAuthorAndCommitter(CommitCommand commitCommand) throws TeamException {
+		final Date commitDate = new Date();
+		final TimeZone timeZone = TimeZone.getDefault();
+
+		final PersonIdent enteredAuthor = RawParseUtils.parsePersonIdent(author);
+		final PersonIdent enteredCommitter = RawParseUtils.parsePersonIdent(committer);
+		if (enteredAuthor == null)
+			throw new TeamException(NLS.bind(
+					CoreText.CommitOperation_errorParsingPersonIdent, author));
+		if (enteredCommitter == null)
+			throw new TeamException(
+					NLS.bind(CoreText.CommitOperation_errorParsingPersonIdent,
+							committer));
+
+		PersonIdent authorIdent = new PersonIdent(enteredAuthor, commitDate, timeZone);
+		final PersonIdent committerIdent = new PersonIdent(enteredCommitter, commitDate, timeZone);
+
+		if (amending) {
+			RepositoryUtil repoUtil = Activator.getDefault().getRepositoryUtil();
+			RevCommit headCommit = repoUtil.parseHeadCommit(repo);
+			if (headCommit != null) {
+				final PersonIdent headAuthor = headCommit.getAuthorIdent();
+				authorIdent = new PersonIdent(enteredAuthor,
+						headAuthor.getWhen(), headAuthor.getTimeZone());
+			}
+		}
+
+		commitCommand.setAuthor(authorIdent);
+		commitCommand.setCommitter(committerIdent);
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/ConfigureFetchAfterCloneTask.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/ConfigureFetchAfterCloneTask.java
new file mode 100644
index 0000000..0387e2f
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/ConfigureFetchAfterCloneTask.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (C) 2011-2012, Stefan Lay <stefan.lay@sap.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.CoreText;
+import org.eclipse.egit.core.internal.op.CloneOperation.PostCloneTask;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.transport.RefSpec;
+import org.eclipse.jgit.transport.RemoteConfig;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Adds a fetch specification of the cloned repository and performs a fetch
+ */
+public class ConfigureFetchAfterCloneTask implements PostCloneTask {
+
+	private String fetchRefSpec;
+
+	private final String remoteName;
+
+	/**
+	 * @param remoteName name of the remote in the git config file
+	 * @param fetchRefSpec the fetch ref spec which will be added
+	 */
+	public ConfigureFetchAfterCloneTask(String remoteName, String fetchRefSpec) {
+		this.remoteName = remoteName;
+		this.fetchRefSpec = fetchRefSpec;
+	}
+
+	/**
+	 * @param repository the cloned repository
+	 * @param monitor
+	 * @throws CoreException
+	 */
+	public void execute(Repository repository, IProgressMonitor monitor)
+			throws CoreException {
+		try {
+			RemoteConfig configToUse = new RemoteConfig(
+					repository.getConfig(), remoteName);
+			if (fetchRefSpec != null)
+				configToUse.addFetchRefSpec(new RefSpec(fetchRefSpec));
+			configToUse.update(repository.getConfig());
+			repository.getConfig().save();
+			Git git = new Git(repository);
+			try {
+				git.fetch().setRemote(remoteName).call();
+			} catch (Exception e) {
+				Activator.logError(NLS.bind(CoreText.ConfigureFetchAfterCloneTask_couldNotFetch, fetchRefSpec), e);
+			}
+		} catch (Exception e) {
+			throw new CoreException(Activator.error(e.getMessage(), e));
+		}
+
+	}
+
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/ConfigurePushAfterCloneTask.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/ConfigurePushAfterCloneTask.java
new file mode 100644
index 0000000..5517732
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/ConfigurePushAfterCloneTask.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (C) 2011, Stefan Lay <stefan.lay@sap.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.op.CloneOperation.PostCloneTask;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.transport.RefSpec;
+import org.eclipse.jgit.transport.RemoteConfig;
+import org.eclipse.jgit.transport.URIish;
+
+/**
+ * Configures the push specification of the cloned repository
+ */
+public class ConfigurePushAfterCloneTask implements PostCloneTask {
+
+	private String pushRefSpec;
+
+	private URIish pushURI;
+
+	private final String remoteName;
+
+	/**
+	 * @param remoteName
+	 * @param pushRefSpec
+	 * @param pushURI
+	 */
+	public ConfigurePushAfterCloneTask(String remoteName, String pushRefSpec, URIish pushURI) {
+		this.remoteName = remoteName;
+		this.pushRefSpec = pushRefSpec;
+		this.pushURI = pushURI;
+	}
+
+	/**
+	 * @param repository
+	 * @param monitor
+	 * @throws CoreException
+	 */
+	public void execute(Repository repository, IProgressMonitor monitor)
+			throws CoreException {
+		try {
+			RemoteConfig configToUse = new RemoteConfig(
+					repository.getConfig(), remoteName);
+			if (pushRefSpec != null)
+				configToUse.addPushRefSpec(new RefSpec(pushRefSpec));
+			if (pushURI != null)
+				configToUse.addPushURI(pushURI);
+			configToUse.update(repository.getConfig());
+			repository.getConfig().save();
+		} catch (Exception e) {
+			throw new CoreException(Activator.error(e.getMessage(), e));
+		}
+
+	}
+
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/ConnectProviderOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/ConnectProviderOperation.java
new file mode 100644
index 0000000..decc6af
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/ConnectProviderOperation.java
@@ -0,0 +1,220 @@
+/*******************************************************************************
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
+ * Copyright (C) 2008, Google Inc.
+ * Copyright (C) 2009, Mykola Nikishov <mn@mn.com.ua>
+ * Copyright (C) 2013, Matthias Sohn <matthias.sohn@sap.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.core.runtime.jobs.MultiRule;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.CoreText;
+import org.eclipse.egit.core.internal.GitProvider;
+import org.eclipse.egit.core.internal.project.GitProjectData;
+import org.eclipse.egit.core.internal.project.RepositoryFinder;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.egit.core.internal.trace.GitTraceLocation;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.team.core.RepositoryProvider;
+
+/**
+ * Connects Eclipse to an existing Git repository
+ */
+public class ConnectProviderOperation implements IEGitOperation {
+	private final Map<IProject, File> projects = new HashMap<IProject, File>();
+
+	/**
+	 * Create a new connection operation to execute within the workspace.
+	 * <p>
+	 * Uses <code>.git</code> as a default relative path to repository.
+	 * @see #ConnectProviderOperation(IProject, File)
+	 *
+	 * @param proj
+	 *            the project to connect to the Git team provider.
+	 */
+	public ConnectProviderOperation(final IProject proj) {
+		this(proj, proj.getLocation().append(Constants.DOT_GIT).toFile());
+	}
+
+	/**
+	 * Create a new connection operation to execute within the workspace.
+	 *
+	 * @param proj
+	 *            the project to connect to the Git team provider.
+	 * @param pathToRepo
+	 *            absolute path to the repository
+	 */
+	public ConnectProviderOperation(final IProject proj, File pathToRepo) {
+		this.projects.put(proj, pathToRepo);
+	}
+
+	/**
+	 * Create a new connection operation to execute within the workspace.
+	 *
+	 * @param projects
+	 *            the projects to connect to the Git team provider.
+	 */
+	public ConnectProviderOperation(final Map<IProject, File> projects) {
+		this.projects.putAll(projects);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.egit.core.op.IEGitOperation#execute(org.eclipse.core.runtime.IProgressMonitor)
+	 */
+	public void execute(IProgressMonitor m) throws CoreException {
+		IProgressMonitor monitor;
+		if (m == null) {
+			monitor = new NullProgressMonitor();
+		} else {
+			monitor = m;
+		}
+
+		monitor.beginTask(CoreText.ConnectProviderOperation_connecting,
+				100 * projects.size());
+		try {
+
+			for (Iterator iterator = projects.keySet().iterator(); iterator.hasNext();) {
+				IProject project = (IProject) iterator.next();
+				monitor.setTaskName(NLS.bind(
+						CoreText.ConnectProviderOperation_ConnectingProject,
+						project.getName()));
+				// TODO is this the right location?
+				if (GitTraceLocation.CORE.isActive())
+					GitTraceLocation.getTrace().trace(
+							GitTraceLocation.CORE.getLocation(),
+							"Locating repository for " + project); //$NON-NLS-1$
+
+				Collection<RepositoryMapping> repos = new RepositoryFinder(
+						project).find(new SubProgressMonitor(monitor, 40));
+				File suggestedRepo = projects.get(project);
+				RepositoryMapping actualMapping= findActualRepository(repos, suggestedRepo);
+				if (actualMapping != null) {
+					GitProjectData projectData = new GitProjectData(project);
+					try {
+						projectData.setRepositoryMappings(Arrays.asList(actualMapping));
+						projectData.store();
+						GitProjectData.add(project, projectData);
+					} catch (CoreException ce) {
+						try {
+							GitProjectData.delete(project);
+						} catch (IOException e) {
+							MultiStatus status = new MultiStatus(
+									Activator.getPluginId(), IStatus.ERROR,
+									e.getMessage(), e);
+							status.add(new Status(IStatus.ERROR, Activator
+									.getPluginId(), ce.getMessage(), ce));
+							throw new CoreException(status);
+						}
+						throw ce;
+					} catch (RuntimeException ce) {
+						try {
+							GitProjectData.delete(project);
+						} catch (IOException e) {
+							MultiStatus status = new MultiStatus(
+									Activator.getPluginId(), IStatus.ERROR,
+									e.getMessage(), e);
+							status.add(new Status(IStatus.ERROR, Activator
+									.getPluginId(), ce.getMessage(), ce));
+							throw new CoreException(status);
+					}
+						throw ce;
+					}
+					RepositoryProvider
+							.map(project, GitProvider.class.getName());
+					autoIgnoreDerivedResources(project, monitor);
+					project.refreshLocal(IResource.DEPTH_INFINITE,
+							new SubProgressMonitor(monitor, 50));
+					monitor.worked(10);
+				} else {
+					// TODO is this the right location?
+					if (GitTraceLocation.CORE.isActive())
+						GitTraceLocation.getTrace().trace(
+								GitTraceLocation.CORE.getLocation(),
+								"Attempted to share project without repository ignored :" //$NON-NLS-1$
+										+ project);
+					monitor.worked(60);
+				}
+			}
+		} finally {
+			monitor.done();
+		}
+	}
+
+	private void autoIgnoreDerivedResources(IProject project,
+			IProgressMonitor monitor) throws CoreException {
+		List<IPath> paths = findDerivedResources(project);
+		if (paths.size() > 0) {
+			IgnoreOperation ignoreOp = new IgnoreOperation(paths);
+			IProgressMonitor subMonitor = new SubProgressMonitor(monitor, 1);
+			ignoreOp.execute(subMonitor);
+		}
+	}
+
+	private List<IPath> findDerivedResources(IContainer c)
+			throws CoreException {
+		List<IPath> derived = new ArrayList<IPath>();
+		IResource[] members = c.members(IContainer.INCLUDE_HIDDEN);
+		for (IResource r : members) {
+			if (r.isDerived())
+				derived.add(r.getLocation());
+			else if (r instanceof IContainer)
+				derived.addAll(findDerivedResources((IContainer) r));
+		}
+		return derived;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.egit.core.op.IEGitOperation#getSchedulingRule()
+	 */
+	public ISchedulingRule getSchedulingRule() {
+		Set<IProject> projectSet = projects.keySet();
+		return new MultiRule(projectSet.toArray(new IProject[projectSet.size()]));
+	}
+
+	/**
+	 * @param repos
+	 *         available repositories
+	 * @param suggestedRepo
+	 *         relative path to git repository
+	 * @return a repository mapping which corresponds to a suggested repository
+	 *         location, <code>null</code> otherwise
+	 */
+	private RepositoryMapping findActualRepository(
+			Collection<RepositoryMapping> repos, File suggestedRepo) {
+		for (RepositoryMapping rm : repos) {
+			if (rm.getGitDirAbsolutePath().equals(Path.fromOSString(suggestedRepo.getPath())))
+				return rm;
+		}
+		return null;
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/CreateLocalBranchOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/CreateLocalBranchOperation.java
new file mode 100644
index 0000000..58a8773
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/CreateLocalBranchOperation.java
@@ -0,0 +1,147 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Mathias Kinzler <mathias.kinzler@sap.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import java.io.IOException;
+
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.CoreText;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.CreateBranchCommand.SetupUpstreamMode;
+import org.eclipse.jgit.lib.ConfigConstants;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.lib.StoredConfig;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * This class implements creation of a local branch based on a commit or another
+ * branch
+ */
+public class CreateLocalBranchOperation implements IEGitOperation {
+	private final String name;
+
+	private final Repository repository;
+
+	private final Ref ref;
+
+	private final RevCommit commit;
+
+	private final UpstreamConfig upstreamConfig;
+
+	/**
+	 * @param repository
+	 * @param name
+	 *            the name for the new local branch (without prefix)
+	 * @param ref
+	 *            the branch or tag to base the new branch upon
+	 * @param config
+	 *            how to do the upstream configuration
+	 */
+	public CreateLocalBranchOperation(Repository repository, String name,
+			Ref ref, UpstreamConfig config) {
+		this.name = name;
+		this.repository = repository;
+		this.ref = ref;
+		this.commit = null;
+		this.upstreamConfig = config;
+	}
+
+	/**
+	 * @param repository
+	 * @param name
+	 *            the name for the new local branch (without prefix)
+	 * @param commit
+	 *            a commit to base the new branch upon
+	 */
+	public CreateLocalBranchOperation(Repository repository, String name,
+			RevCommit commit) {
+		this.name = name;
+		this.repository = repository;
+		this.ref = null;
+		this.commit = commit;
+		this.upstreamConfig = null;
+	}
+
+	public void execute(IProgressMonitor m) throws CoreException {
+		IProgressMonitor monitor;
+		if (m == null)
+			monitor = new NullProgressMonitor();
+		else
+			monitor = m;
+
+		IWorkspaceRunnable action = new IWorkspaceRunnable() {
+			public void run(IProgressMonitor actMonitor) throws CoreException {
+				String taskName = NLS
+						.bind(
+								CoreText.CreateLocalBranchOperation_CreatingBranchMessage,
+								name);
+				actMonitor.beginTask(taskName, 1);
+				Git git = new Git(repository);
+				try {
+					if (ref != null) {
+						SetupUpstreamMode mode;
+						if (upstreamConfig == UpstreamConfig.NONE)
+							mode = SetupUpstreamMode.NOTRACK;
+						else
+							mode = SetupUpstreamMode.SET_UPSTREAM;
+						git.branchCreate().setName(name).setStartPoint(
+								ref.getName()).setUpstreamMode(mode).call();
+					}
+					else
+						git.branchCreate().setName(name).setStartPoint(commit)
+								.setUpstreamMode(SetupUpstreamMode.NOTRACK)
+								.call();
+				} catch (Exception e) {
+					throw new CoreException(Activator.error(e.getMessage(), e));
+				}
+
+				if (UpstreamConfig.REBASE == upstreamConfig) {
+					// set "branch.<name>.rebase" to "true"
+					StoredConfig config = repository.getConfig();
+					config.setBoolean(ConfigConstants.CONFIG_BRANCH_SECTION,
+							name, ConfigConstants.CONFIG_KEY_REBASE, true);
+					try {
+						config.save();
+					} catch (IOException e) {
+						throw new CoreException(Activator.error(e.getMessage(),
+								e));
+					}
+				}
+				actMonitor.worked(1);
+				actMonitor.done();
+			}
+		};
+		// lock workspace to protect working tree changes
+		ResourcesPlugin.getWorkspace().run(action, monitor);
+	}
+
+	public ISchedulingRule getSchedulingRule() {
+		return ResourcesPlugin.getWorkspace().getRoot();
+	}
+
+	/**
+	 * Describes how to configure the upstream branch
+	 */
+	public static enum UpstreamConfig {
+		/** Rebase */
+		REBASE(),
+		/** Merge */
+		MERGE(),
+		/** No configuration */
+		NONE();
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/CreatePatchOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/CreatePatchOperation.java
new file mode 100644
index 0000000..d2c4156
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/CreatePatchOperation.java
@@ -0,0 +1,468 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2012 SAP AG and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Stefan Lay (SAP AG) - initial implementation
+ *    Benjamin Muskalla (Tasktop Technologies) - extract into operation
+ *    Tomasz Zarna (IBM Corporation) - bug 370332
+ *    Daniel Megert <daniel_megert@ch.ibm.com> - Allow spaces in path
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import static org.eclipse.jgit.lib.Constants.encodeASCII;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.text.SimpleDateFormat;
+import java.util.List;
+import java.util.Locale;
+import java.util.Stack;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.core.filesystem.URIUtil;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.CompareCoreUtils;
+import org.eclipse.egit.core.internal.CoreText;
+import org.eclipse.egit.core.internal.EclipseGitProgressTransformer;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.jgit.diff.DiffEntry;
+import org.eclipse.jgit.diff.DiffEntry.ChangeType;
+import org.eclipse.jgit.diff.DiffEntry.Side;
+import org.eclipse.jgit.diff.DiffFormatter;
+import org.eclipse.jgit.diff.RawText;
+import org.eclipse.jgit.dircache.DirCacheIterator;
+import org.eclipse.jgit.errors.CorruptObjectException;
+import org.eclipse.jgit.errors.MissingObjectException;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.treewalk.FileTreeIterator;
+import org.eclipse.jgit.treewalk.filter.TreeFilter;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Creates a patch for a specific commit
+ */
+public class CreatePatchOperation implements IEGitOperation {
+
+	/**
+	 * Diff header format
+	 *
+	 */
+	public enum DiffHeaderFormat {
+		/**
+		 * No header
+		 */
+		NONE(CoreText.DiffHeaderFormat_None, false, null),
+
+		/**
+		 * Workspace patch
+		 */
+		WORKSPACE(CoreText.DiffHeaderFormat_Workspace, false, "### Eclipse Workspace Patch 1.0\n"), //$NON-NLS-1$
+
+		/**
+		 * Email header
+		 */
+		EMAIL(CoreText.DiffHeaderFormat_Email, true, "From ${sha1} ${date}\nFrom: ${author}\nDate: ${author date}\nSubject: [PATCH] ${title line}\n${full commit message}\n"), //$NON-NLS-1$
+
+		/**
+		 * Header designed to be as compact as possible
+		 */
+		ONELINE(CoreText.DiffHeaderFormat_Oneline, true, "${sha1} ${title line}\n"); //$NON-NLS-1$
+
+		private final String description;
+
+		private final boolean commitRequired;
+
+		private final String template;
+
+		private DiffHeaderFormat(final String d, final boolean c, final String t) {
+			description = d;
+			commitRequired = c;
+			template = t;
+		}
+
+		/**
+		 * @return if this format requires a commit.
+		 */
+		public boolean isCommitRequired() {
+			return commitRequired;
+		}
+
+		/**
+		 * @return the template
+		 */
+		public String getTemplate() {
+			return template;
+		}
+
+		/**
+		 * @return the description
+		 */
+		public String getDescription() {
+			return description;
+		}
+	}
+
+	enum DiffHeaderKeyword{
+		SHA1, AUTHOR_DATE, AUTHOR, DATE, TITLE_LINE, FULL_COMMIT_MESSAGE
+	}
+
+	/**
+	 * The default number of lines to use as context
+	 */
+	public static final int DEFAULT_CONTEXT_LINES = 3;
+
+	private final RevCommit commit;
+
+	private final Repository repository;
+
+	private DiffHeaderFormat headerFormat = DiffHeaderFormat.EMAIL;
+
+	// the encoding for the currently processed file
+	private String currentEncoding = null;
+
+	private String patchContent;
+
+	private int contextLines = DEFAULT_CONTEXT_LINES;
+
+	private TreeFilter pathFilter = null;
+
+	/**
+	 * Creates the new operation.
+	 *
+	 * @param repository
+	 * @param commit
+	 */
+	public CreatePatchOperation(Repository repository, RevCommit commit) {
+		if (repository == null)
+			throw new IllegalArgumentException(
+					CoreText.CreatePatchOperation_repoRequired);
+		this.repository = repository;
+		this.commit = commit;
+	}
+
+	public void execute(IProgressMonitor monitor) throws CoreException {
+		EclipseGitProgressTransformer gitMonitor;
+		if (monitor == null)
+			gitMonitor = new EclipseGitProgressTransformer(
+					new NullProgressMonitor());
+		else
+			gitMonitor = new EclipseGitProgressTransformer(monitor);
+
+		final StringBuilder sb = new StringBuilder();
+		final DiffFormatter diffFmt = new DiffFormatter(
+				new ByteArrayOutputStream() {
+
+					@Override
+					public synchronized void write(byte[] b, int off, int len) {
+						super.write(b, off, len);
+						if (currentEncoding == null)
+							sb.append(toString());
+						else
+							try {
+								sb.append(toString(currentEncoding));
+							} catch (UnsupportedEncodingException e) {
+								sb.append(toString());
+							}
+						reset();
+					}
+				}) {
+			private IProject project;
+
+			@Override
+			public void format(DiffEntry ent) throws IOException,
+					CorruptObjectException, MissingObjectException {
+				// for "workspace patches" add project header each time project changes
+				if (DiffHeaderFormat.WORKSPACE == headerFormat) {
+					IProject p = getProject(ent);
+					if (!p.equals(project)) {
+						project = p;
+						getOutputStream().write(
+								encodeASCII("#P " + project.getName() + "\n")); //$NON-NLS-1$ //$NON-NLS-2$
+					}
+				}
+				super.format(ent);
+			}
+		};
+
+		diffFmt.setProgressMonitor(gitMonitor);
+		diffFmt.setContext(contextLines);
+
+		if (headerFormat != null && headerFormat != DiffHeaderFormat.NONE)
+			writeGitPatchHeader(sb);
+
+		diffFmt.setRepository(repository);
+		diffFmt.setPathFilter(pathFilter);
+
+		try {
+			if (commit != null) {
+				RevCommit[] parents = commit.getParents();
+				if (parents.length > 1)
+					throw new IllegalStateException(
+							CoreText.CreatePatchOperation_cannotCreatePatchForMergeCommit);
+				if (parents.length == 0)
+					throw new IllegalStateException(
+							CoreText.CreatePatchOperation_cannotCreatePatchForFirstCommit);
+
+				List<DiffEntry> diffs = diffFmt.scan(parents[0].getId(),commit.getId());
+				for (DiffEntry ent : diffs) {
+					String path;
+					if (ChangeType.DELETE.equals(ent.getChangeType()))
+						path = ent.getOldPath();
+					else
+						path = ent.getNewPath();
+					currentEncoding = CompareCoreUtils.getResourceEncoding(repository, path);
+					diffFmt.format(ent);
+				}
+			} else
+				diffFmt.format(
+						new DirCacheIterator(repository.readDirCache()),
+						new FileTreeIterator(repository));
+		} catch (IOException e) {
+			Activator.logError(CoreText.CreatePatchOperation_patchFileCouldNotBeWritten, e);
+		}
+
+		if (DiffHeaderFormat.WORKSPACE == headerFormat)
+			updateWorkspacePatchPrefixes(sb, diffFmt);
+
+		// trim newline
+		if (sb.charAt(sb.length() - 1) == '\n')
+			sb.setLength(sb.length() - 1);
+
+		patchContent = sb.toString();
+	}
+
+	private IProject getProject(final DiffEntry ent) {
+		Side side = ent.getChangeType() == ChangeType.ADD ? Side.NEW : Side.OLD;
+		String path = ent.getPath(side);
+		return getProject(path);
+	}
+
+	private IProject getProject(String path) {
+		URI pathUri = repository.getWorkTree().toURI().resolve(URIUtil.toURI(path));
+		IFile[] files = ResourcesPlugin.getWorkspace().getRoot()
+				.findFilesForLocationURI(pathUri);
+		Assert.isLegal(files.length == 1, NLS.bind(CoreText.CreatePatchOperation_couldNotFindProject, path, repository));
+		return files[0].getProject();
+	}
+
+	/**
+	 * Retrieves the content of the requested patch
+	 *
+	 * @return the content of the patch
+	 */
+	public String getPatchContent() {
+		if (patchContent == null)
+			throw new IllegalStateException(
+					"#execute needs to be called before this method."); //$NON-NLS-1$
+		return patchContent;
+	}
+
+	private void writeGitPatchHeader(StringBuilder sb) {
+		String template = headerFormat.getTemplate();
+		String[] segments = template.split("\\$\\{"); //$NON-NLS-1$
+		Stack<String> evaluated = new Stack<String>();
+		evaluated.add(segments[0]);
+
+		for (int i = 1; i < segments.length; i++) {
+			String segment = segments[i];
+			String value = null;
+			int brace = segment.indexOf('}');
+			if (brace > 0) {
+				String keyword = segment.substring(0, brace);
+				keyword = keyword.toUpperCase().replaceAll(" ", "_"); //$NON-NLS-1$ //$NON-NLS-2$
+				value = processKeyword(commit, DiffHeaderKeyword.valueOf(keyword));
+			}
+
+			String trailingCharacters = segment.substring(brace + 1);
+			if (value != null) {
+				evaluated.add(value);
+				evaluated.add(trailingCharacters);
+			} else if (!evaluated.isEmpty())
+				evaluated.add(trailingCharacters);
+		}
+		StringBuffer buffer = new StringBuffer();
+		for (String string : evaluated)
+			buffer.append(string);
+
+		sb.append(buffer);
+	}
+
+	private static String processKeyword(RevCommit commit, DiffHeaderKeyword keyword) {
+		final SimpleDateFormat dtfmt = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z", Locale.US); //$NON-NLS-1$
+		switch (keyword) {
+		case SHA1:
+			return commit.getId().getName();
+		case AUTHOR:
+			return commit.getAuthorIdent().getName()
+					+ " <" + commit.getAuthorIdent().getEmailAddress() + ">"; //$NON-NLS-1$ //$NON-NLS-2$
+		case AUTHOR_DATE:
+			dtfmt.setTimeZone(commit.getAuthorIdent().getTimeZone());
+			return dtfmt.format(commit.getAuthorIdent().getWhen());
+		case DATE:
+			return dtfmt.format(Long.valueOf(System.currentTimeMillis()));
+		case TITLE_LINE:
+			return commit.getShortMessage();
+		case FULL_COMMIT_MESSAGE:
+			return commit.getFullMessage().substring(
+					commit.getShortMessage().length());
+		default:
+			return null;
+		}
+	}
+
+	/**
+	 * Updates prefixes to workspace paths
+	 *
+	 * @param sb
+	 * @param diffFmt
+	 */
+	public void updateWorkspacePatchPrefixes(StringBuilder sb, DiffFormatter diffFmt) {
+		RawText rt = new RawText(sb.toString().getBytes());
+
+		final String oldPrefix = diffFmt.getOldPrefix();
+		final String newPrefix = diffFmt.getNewPrefix();
+
+		StringBuilder newSb = new StringBuilder();
+		final Pattern diffPattern = Pattern
+				.compile("^diff --git (" + oldPrefix + "(.+)) (" + newPrefix + "(.+))$"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		final Pattern oldPattern = Pattern
+				.compile("^--- (" + oldPrefix + "(.+))$"); //$NON-NLS-1$ //$NON-NLS-2$
+		final Pattern newPattern = Pattern
+				.compile("^\\+\\+\\+ (" + newPrefix + "(.+))$"); //$NON-NLS-1$ //$NON-NLS-2$
+
+		int i = 0;
+		while (i < rt.size()) {
+			String line = rt.getString(i);
+
+			Matcher diffMatcher = diffPattern.matcher(line);
+			Matcher oldMatcher = oldPattern.matcher(line);
+			Matcher newMatcher = newPattern.matcher(line);
+			if (diffMatcher.find()) {
+				String group = diffMatcher.group(2); // old path
+				IProject project = getProject(group);
+				IPath newPath = computeWorkspacePath(new Path(group), project);
+				line = line.replaceAll(diffMatcher.group(1), newPath.toString());
+				group = diffMatcher.group(4); // new path
+				newPath = computeWorkspacePath(new Path(group), project);
+				line = line.replaceAll(diffMatcher.group(3), newPath.toString());
+			} else if (oldMatcher.find()) {
+				String group = oldMatcher.group(2);
+				IProject project = getProject(group);
+				IPath newPath = computeWorkspacePath(new Path(group), project);
+				line = line.replaceAll(oldMatcher.group(1), newPath.toString());
+			} else if (newMatcher.find()) {
+				String group = newMatcher.group(2);
+				IProject project = getProject(group);
+				IPath newPath = computeWorkspacePath(new Path(group), project);
+				line = line.replaceAll(newMatcher.group(1), newPath.toString());
+			}
+			newSb.append(line);
+
+			i++;
+			if (i < rt.size() || !rt.isMissingNewlineAtEnd())
+				newSb.append(rt.getLineDelimiter());
+		}
+		// reset sb to newSb
+		sb.setLength(0);
+		sb.append(newSb);
+	}
+
+	/**
+	 * Returns a workspace path
+	 *
+	 * @param path
+	 * @param project
+	 * @return path
+	 */
+	public static IPath computeWorkspacePath(final IPath path, final IProject project) {
+		RepositoryMapping rm = RepositoryMapping.getMapping(project);
+		String repoRelativePath = rm.getRepoRelativePath(project);
+		// the relative path cannot be determined, return unchanged
+		if (repoRelativePath == null)
+			return path;
+		// repository and project at the same level
+		if (repoRelativePath.equals("")) //$NON-NLS-1$
+			return path;
+		return path.removeFirstSegments(path.matchingFirstSegments(new Path(
+				repoRelativePath)));
+	}
+
+
+	/**
+	 * Change the format of diff header
+	 *
+	 * @param format header format
+	 */
+	public void setHeaderFormat(DiffHeaderFormat format) {
+		this.headerFormat = format;
+	}
+
+	/**
+	 * Change the number of lines of context to display.
+	 *
+	 * @param contextLines line count
+	 */
+	public void setContextLines(int contextLines) {
+		this.contextLines = contextLines;
+	}
+
+	/**
+	 * Suggests a file name for the patch given the commit.
+	 *
+	 * @param commit
+	 * @return a file name for a patch
+	 */
+	public static String suggestFileName(RevCommit commit) {
+		String name = commit.getShortMessage();
+
+		name = name.trim();
+		StringBuilder filteredBuilder = new StringBuilder();
+		char[] charArray = name.toCharArray();
+		for (char c : charArray) {
+			if(Character.isLetter(c) || Character.isDigit(c))
+				filteredBuilder.append(c);
+			if(Character.isWhitespace(c) || c == '/')
+				filteredBuilder.append("-"); //$NON-NLS-1$
+		}
+		name = filteredBuilder.toString();
+		if (name.length() > 52)
+			name = name.substring(0, 52);
+		while (name.endsWith(".")) //$NON-NLS-1$
+			name = name.substring(0, name.length() - 1);
+		name = name.concat(".patch"); //$NON-NLS-1$
+
+		return name;
+	}
+
+	public ISchedulingRule getSchedulingRule() {
+		return null;
+	}
+
+	/**
+	 * Set the filter to produce patch for specified paths only.
+	 *
+	 * @param pathFilter the filter
+	 */
+	public void setPathFilter(TreeFilter pathFilter) {
+		this.pathFilter = pathFilter;
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/DeleteBranchOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/DeleteBranchOperation.java
new file mode 100644
index 0000000..317a2ca
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/DeleteBranchOperation.java
@@ -0,0 +1,148 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Mathias Kinzler <mathias.kinzler@sap.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import static java.util.Arrays.asList;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.CoreText;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.CannotDeleteCurrentBranchException;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.api.errors.JGitInternalException;
+import org.eclipse.jgit.api.errors.NotMergedException;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * This class implements deletion of a branch
+ */
+public class DeleteBranchOperation implements IEGitOperation {
+	/** Operation was performed */
+	public final static int OK = 0;
+
+	/** Current branch can not be deleted */
+	public final static int REJECTED_CURRENT = 1;
+
+	/**
+	 * Branch to be deleted has not been fully merged; use force to delete
+	 * anyway
+	 */
+	public final static int REJECTED_UNMERGED = 2;
+
+	/** This operation was not executed yet */
+	public final static int NOT_TRIED = -1;
+
+	private int status = NOT_TRIED;
+
+	private final Repository repository;
+
+	private final Set<Ref> branches;
+
+	private final boolean force;
+
+	/**
+	 * @param repository
+	 * @param branch
+	 *            the branch to delete
+	 * @param force
+	 */
+	public DeleteBranchOperation(Repository repository, Ref branch,
+			boolean force) {
+		this(repository, new HashSet<Ref>(asList(branch)), force);
+	}
+
+	/**
+	 * @param repository
+	 * @param branches
+	 *            the list of branches to deleted
+	 * @param force
+	 */
+	public DeleteBranchOperation(Repository repository, Set<Ref> branches,
+			boolean force) {
+		this.repository = repository;
+		this.branches = branches;
+		this.force = force;
+	}
+
+	/**
+	 * @return one of {@link #OK}, {@link #REJECTED_CURRENT},
+	 *         {@link #REJECTED_UNMERGED}, {@link #NOT_TRIED}
+	 */
+	public int getStatus() {
+		return status;
+	}
+
+	public void execute(IProgressMonitor m) throws CoreException {
+		IProgressMonitor monitor;
+		if (m == null)
+			monitor = new NullProgressMonitor();
+		else
+			monitor = m;
+
+		IWorkspaceRunnable action = new IWorkspaceRunnable() {
+			public void run(IProgressMonitor actMonitor) throws CoreException {
+
+				String taskName;
+				if (branches.size() == 1)
+					taskName = NLS.bind(
+							CoreText.DeleteBranchOperation_TaskName, branches
+									.iterator().next().getName());
+				else {
+					StringBuilder names = new StringBuilder();
+					for (Iterator<Ref> it = branches.iterator(); it.hasNext(); ) {
+						Ref ref = it.next();
+						names.append(ref.getName());
+						if (it.hasNext())
+							names.append(", "); //$NON-NLS-1$
+					}
+					taskName = NLS.bind(
+							CoreText.DeleteBranchOperation_TaskName, names);
+				}
+				actMonitor.beginTask(taskName, branches.size());
+				for (Ref branch : branches) {
+					try {
+						new Git(repository).branchDelete().setBranchNames(
+								branch.getName()).setForce(force).call();
+						status = OK;
+					} catch (NotMergedException e) {
+						status = REJECTED_UNMERGED;
+						break;
+					} catch (CannotDeleteCurrentBranchException e) {
+						status = REJECTED_CURRENT;
+						break;
+					} catch (JGitInternalException e) {
+						throw new CoreException(Activator.error(e.getMessage(), e));
+					} catch (GitAPIException e) {
+						throw new CoreException(Activator.error(e.getMessage(), e));
+					}
+					actMonitor.worked(1);
+				}
+				actMonitor.done();
+			}
+		};
+		// lock workspace to protect working tree changes
+		ResourcesPlugin.getWorkspace().run(action, monitor);
+	}
+
+	public ISchedulingRule getSchedulingRule() {
+		return ResourcesPlugin.getWorkspace().getRoot();
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/DeletePathsOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/DeletePathsOperation.java
new file mode 100644
index 0000000..6a23aa1
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/DeletePathsOperation.java
@@ -0,0 +1,139 @@
+/*******************************************************************************
+ * Copyright (C) 2012, Robin Stocker <robin@nibor.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import java.io.File;
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.CoreText;
+import org.eclipse.egit.core.internal.indexdiff.IndexDiffCache;
+import org.eclipse.egit.core.internal.indexdiff.IndexDiffCacheEntry;
+import org.eclipse.egit.core.internal.job.RuleUtil;
+import org.eclipse.egit.core.internal.util.ResourceUtil;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.util.FileUtils;
+
+/**
+ * Operation to delete a collection of (untracked) paths, even it they are
+ * non-workspace resources.
+ */
+public class DeletePathsOperation implements IEGitOperation {
+
+	private final Collection<IPath> paths;
+
+	private final ISchedulingRule schedulingRule;
+
+	/**
+	 * @param paths
+	 *            the files to delete
+	 */
+	public DeletePathsOperation(final Collection<IPath> paths) {
+		this.paths = paths;
+		schedulingRule = calculateSchedulingRule();
+	}
+
+	public void execute(IProgressMonitor m) throws CoreException {
+		IProgressMonitor monitor = (m != null) ? m : new NullProgressMonitor();
+		IWorkspaceRunnable action = new IWorkspaceRunnable() {
+			public void run(IProgressMonitor actMonitor) throws CoreException {
+				deletePaths(actMonitor);
+			}
+		};
+		ResourcesPlugin.getWorkspace().run(action, getSchedulingRule(),
+				IWorkspace.AVOID_UPDATE, monitor);
+	}
+
+	public ISchedulingRule getSchedulingRule() {
+		return schedulingRule;
+	}
+
+	private void deletePaths(IProgressMonitor monitor) throws CoreException {
+		monitor.beginTask(CoreText.DeleteResourcesOperation_deletingResources,
+				paths.size() + 1);
+		boolean errorOccurred = false;
+
+		boolean refreshAll = false;
+		List<IPath> refreshCachePaths = new ArrayList<IPath>();
+
+		for (IPath path : paths) {
+			IResource resource = ResourceUtil.getResourceForLocation(path);
+			if (resource != null && resource.exists())
+				resource.delete(false, new SubProgressMonitor(monitor, 1));
+			else {
+				File file = path.toFile();
+				if (file.exists()) {
+					try {
+						FileUtils.delete(file, FileUtils.RECURSIVE);
+					} catch (IOException e) {
+						errorOccurred = true;
+						String message = MessageFormat
+								.format(CoreText.DeleteResourcesOperation_deleteFailed,
+										file.getPath());
+						Activator.logError(message, e);
+					}
+					refreshCachePaths.add(path);
+					// Selectively refreshing an IndexDiffCacheEntry only works for files,
+					// so refresh all in case of a directory
+					if (file.isDirectory())
+						refreshAll = true;
+				}
+				monitor.worked(1);
+			}
+		}
+
+		if (!refreshCachePaths.isEmpty())
+			refreshIndexDiffCache(refreshCachePaths, refreshAll);
+		monitor.worked(1);
+
+		monitor.done();
+
+		if (errorOccurred) {
+			IStatus status = Activator.error(
+					CoreText.DeleteResourcesOperation_deleteFailedSeeLog, null);
+			throw new CoreException(status);
+		}
+	}
+
+	private ISchedulingRule calculateSchedulingRule() {
+		return RuleUtil.getRuleForContainers(paths);
+	}
+
+	private void refreshIndexDiffCache(List<IPath> refreshCachePaths, boolean refreshAll) {
+		Map<Repository, Collection<String>> resourcesByRepository = ResourceUtil.splitPathsByRepository(refreshCachePaths);
+		for (Map.Entry<Repository, Collection<String>> entry : resourcesByRepository.entrySet()) {
+			Repository repository = entry.getKey();
+			Collection<String> files = entry.getValue();
+
+			IndexDiffCache cache = Activator.getDefault().getIndexDiffCache();
+			IndexDiffCacheEntry cacheEntry = cache.getIndexDiffCacheEntry(repository);
+			if (cacheEntry != null)
+				if (refreshAll)
+					cacheEntry.refresh();
+				else
+					cacheEntry.refreshFiles(files);
+		}
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/DeleteTagOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/DeleteTagOperation.java
new file mode 100644
index 0000000..d56ecde
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/DeleteTagOperation.java
@@ -0,0 +1,54 @@
+/******************************************************************************
+ *  Copyright (c) 2011 GitHub Inc.
+ *  All rights reserved. This program and the accompanying materials
+ *  are made available under the terms of the Eclipse Public License v1.0
+ *  which accompanies this distribution, and is available at
+ *  http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *    Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *****************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.CoreText;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.lib.Repository;
+
+/**
+ * Operation that deletes a tag
+ */
+public class DeleteTagOperation implements IEGitOperation {
+
+	private final Repository repository;
+
+	private final String tag;
+
+	/**
+	 * Create operation that deletes a single tag
+	 *
+	 * @param repository
+	 * @param tag
+	 */
+	public DeleteTagOperation(final Repository repository, final String tag) {
+		this.repository = repository;
+		this.tag = tag;
+	}
+
+	public void execute(IProgressMonitor monitor) throws CoreException {
+		try {
+			Git.wrap(repository).tagDelete().setTags(tag).call();
+		} catch (GitAPIException e) {
+			throw new CoreException(Activator.error(
+					CoreText.DeleteTagOperation_exceptionMessage, e));
+		}
+	}
+
+	public ISchedulingRule getSchedulingRule() {
+		return null;
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/DiscardChangesOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/DiscardChangesOperation.java
new file mode 100644
index 0000000..d6be1ae
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/DiscardChangesOperation.java
@@ -0,0 +1,163 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Jens Baumgart <jens.baumgart@sap.com>
+ * Copyright (C) 2010, Roland Grunberg <rgrunber@redhat.com>
+ * Copyright (C) 2012, Robin Stocker <robin@nibor.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Code extracted from org.eclipse.egit.ui.internal.actions.DiscardChangesAction
+ * and reworked.
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceRuleFactory;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.core.runtime.jobs.MultiRule;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.CoreText;
+import org.eclipse.egit.core.internal.job.RuleUtil;
+import org.eclipse.egit.core.internal.util.ProjectUtil;
+import org.eclipse.egit.core.internal.util.ResourceUtil;
+import org.eclipse.jgit.api.CheckoutCommand;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.lib.Repository;
+
+/**
+ * The operation discards changes on a set of resources. In case of a folder
+ * resource all file resources in the sub tree are processed. Untracked files
+ * are ignored.
+ */
+public class DiscardChangesOperation implements IEGitOperation {
+
+	String revision;
+
+	IResource[] files;
+
+	ISchedulingRule schedulingRule;
+
+	/**
+	 * Construct a {@link DiscardChangesOperation} object.
+	 *
+	 * @param files
+	 */
+	public DiscardChangesOperation(IResource[] files) {
+		this(files, null);
+	}
+
+	/**
+	 * Construct a {@link DiscardChangesOperation} object.
+	 *
+	 * @param files
+	 * @param revision
+	 */
+	public DiscardChangesOperation(IResource[] files, String revision) {
+		this.files = new IResource[files.length];
+		System.arraycopy(files, 0, this.files, 0, files.length);
+		this.revision = revision;
+		schedulingRule = MultiRule.combine(calcRefreshRule(files),
+				RuleUtil.getRuleForRepositories(files));
+	}
+
+	/*
+	 * (non-Javadoc)
+	 *
+	 * @see org.eclipse.egit.core.op.IEGitOperation#getSchedulingRule()
+	 */
+	public ISchedulingRule getSchedulingRule() {
+		return schedulingRule;
+	}
+
+	private static ISchedulingRule calcRefreshRule(IResource[] resources) {
+		List<ISchedulingRule> rules = new ArrayList<ISchedulingRule>();
+		IResourceRuleFactory ruleFactory = ResourcesPlugin.getWorkspace()
+				.getRuleFactory();
+		for (IResource resource : resources) {
+			ISchedulingRule rule = ruleFactory.refreshRule(resource);
+			if (rule != null)
+				rules.add(rule);
+		}
+		if (rules.size() == 0)
+			return null;
+		else
+			return new MultiRule(rules.toArray(new IResource[rules.size()]));
+	}
+
+	public void execute(IProgressMonitor m) throws CoreException {
+		IProgressMonitor monitor;
+		if (m == null)
+			monitor = new NullProgressMonitor();
+		else
+			monitor = m;
+		IWorkspaceRunnable action = new IWorkspaceRunnable() {
+			public void run(IProgressMonitor actMonitor) throws CoreException {
+				discardChanges(actMonitor);
+			}
+		};
+		ResourcesPlugin.getWorkspace().run(action, getSchedulingRule(),
+				IWorkspace.AVOID_UPDATE, monitor);
+	}
+
+	private void discardChanges(IProgressMonitor monitor) throws CoreException {
+		monitor.beginTask(CoreText.DiscardChangesOperation_discardingChanges, 2);
+		boolean errorOccurred = false;
+		try {
+			discardChanges();
+		} catch (GitAPIException e) {
+			errorOccurred = true;
+			Activator.logError(CoreText.DiscardChangesOperation_discardFailed, e);
+		}
+		monitor.worked(1);
+		try {
+			ProjectUtil.refreshResources(files, new SubProgressMonitor(monitor,
+					1));
+		} catch (CoreException e) {
+			errorOccurred = true;
+			Activator.logError(CoreText.DiscardChangesOperation_refreshFailed,
+					e);
+		}
+		monitor.worked(1);
+		monitor.done();
+		if (errorOccurred) {
+			IStatus status = Activator.error(
+					CoreText.DiscardChangesOperation_discardFailedSeeLog, null);
+			throw new CoreException(status);
+		}
+	}
+
+	private void discardChanges() throws GitAPIException {
+		Map<Repository, Collection<String>> pathsByRepository = ResourceUtil
+				.splitResourcesByRepository(files);
+		for (Entry<Repository, Collection<String>> entry : pathsByRepository.entrySet()) {
+			Repository repository = entry.getKey();
+			Collection<String> paths = entry.getValue();
+			CheckoutCommand checkoutCommand = new Git(repository).checkout();
+			checkoutCommand.setStartPoint(this.revision);
+			if (paths.isEmpty() || paths.contains("")) //$NON-NLS-1$
+				checkoutCommand.setAllPaths(true);
+			else
+				for (String path : paths)
+					checkoutCommand.addPath(path);
+			checkoutCommand.call();
+		}
+	}
+
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/DisconnectProviderOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/DisconnectProviderOperation.java
new file mode 100644
index 0000000..d3b11ac
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/DisconnectProviderOperation.java
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * Copyright (C) 2007, Shawn O. Pearce <spearce@spearce.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import java.util.Collection;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.core.runtime.jobs.MultiRule;
+import org.eclipse.egit.core.internal.CoreText;
+import org.eclipse.egit.core.internal.trace.GitTraceLocation;
+import org.eclipse.team.core.RepositoryProvider;
+
+/**
+ * Disconnects the Git team provider from a project.
+ * <p>
+ * Once disconnected, Git operations will no longer be available on the project.
+ * </p>
+ */
+public class DisconnectProviderOperation implements IEGitOperation {
+	private final Collection<IProject> projectList;
+
+	/**
+	 * Create a new disconnect operation.
+	 *
+	 * @param projs
+	 *            the collection of {@link IProject}s which should be
+	 *            disconnected from the Git team provider, and returned to
+	 *            untracked/unmanaged status.
+	 */
+	public DisconnectProviderOperation(final Collection<IProject> projs) {
+		projectList = projs;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.egit.core.op.IEGitOperation#execute(org.eclipse.core.runtime.IProgressMonitor)
+	 */
+	public void execute(IProgressMonitor m) throws CoreException {
+		IProgressMonitor monitor;
+		if (m == null)
+			monitor = new NullProgressMonitor();
+		else
+			monitor = m;
+
+		monitor.beginTask(CoreText.DisconnectProviderOperation_disconnecting,
+				projectList.size() * 200);
+		try {
+			for (IProject p : projectList) {
+				// TODO is this the right location?
+				if (GitTraceLocation.CORE.isActive())
+					GitTraceLocation.getTrace().trace(
+							GitTraceLocation.CORE.getLocation(),
+							"disconnect " + p.getName()); //$NON-NLS-1$
+				unmarkTeamPrivate(p);
+				RepositoryProvider.unmap(p);
+				monitor.worked(100);
+
+				p.refreshLocal(IResource.DEPTH_INFINITE,
+						new SubProgressMonitor(monitor, 100));
+			}
+		} finally {
+			monitor.done();
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.egit.core.op.IEGitOperation#getSchedulingRule()
+	 */
+	public ISchedulingRule getSchedulingRule() {
+		return new MultiRule(projectList.toArray(new IProject[projectList.size()]));
+	}
+
+	private void unmarkTeamPrivate(final IContainer p) throws CoreException {
+		final IResource[] c;
+		c = p.members(IContainer.INCLUDE_TEAM_PRIVATE_MEMBERS);
+		if (c != null) {
+			for (int k = 0; k < c.length; k++) {
+				if (c[k] instanceof IContainer) {
+					unmarkTeamPrivate((IContainer) c[k]);
+				}
+				if (c[k].isTeamPrivateMember()) {
+					// TODO is this the right location?
+					if (GitTraceLocation.CORE.isActive())
+						GitTraceLocation.getTrace().trace(
+								GitTraceLocation.CORE.getLocation(),
+								"notTeamPrivate " + c[k]); //$NON-NLS-1$
+					c[k].setTeamPrivateMember(false);
+				}
+			}
+		}
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/FetchOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/FetchOperation.java
new file mode 100644
index 0000000..66d6b44
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/FetchOperation.java
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Copyright (C) 2011, Mathias Kinzler <mathias.kinzler@sap.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.List;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.egit.core.internal.CoreText;
+import org.eclipse.egit.core.internal.EclipseGitProgressTransformer;
+import org.eclipse.jgit.api.FetchCommand;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.JGitInternalException;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.transport.CredentialsProvider;
+import org.eclipse.jgit.transport.FetchResult;
+import org.eclipse.jgit.transport.RefSpec;
+import org.eclipse.jgit.transport.RemoteConfig;
+import org.eclipse.jgit.transport.TagOpt;
+import org.eclipse.jgit.transport.URIish;
+
+/**
+ * Used to fetch from another Repository
+ */
+public class FetchOperation {
+	private final Repository repository;
+
+	private final RemoteConfig rc;
+
+	private final URIish uri;
+
+	private final int timeout;
+
+	private final List<RefSpec> specs;
+
+	private final boolean dryRun;
+
+	private FetchResult operationResult;
+
+	private CredentialsProvider credentialsProvider;
+
+	private TagOpt tagOpt;
+
+	/**
+	 * Constructs a FetchOperation based on URI and RefSpecs
+	 *
+	 * @param repository
+	 * @param uri
+	 * @param refSpecs
+	 * @param timeout
+	 * @param dryRun
+	 *
+	 */
+	public FetchOperation(Repository repository, URIish uri,
+			List<RefSpec> refSpecs, int timeout, boolean dryRun) {
+		this.repository = repository;
+		this.timeout = timeout;
+		this.dryRun = dryRun;
+		this.uri = uri;
+		this.specs = refSpecs;
+		this.rc = null;
+	}
+
+	/**
+	 * Constructs a FetchOperation based on a RemoteConfig
+	 *
+	 * @param repository
+	 * @param config
+	 * @param timeout
+	 * @param dryRun
+	 */
+	public FetchOperation(Repository repository, RemoteConfig config,
+			int timeout, boolean dryRun) {
+		this.repository = repository;
+		this.timeout = timeout;
+		this.dryRun = dryRun;
+		this.uri = null;
+		this.specs = null;
+		this.rc = config;
+	}
+
+	/**
+	 * @param credentialsProvider
+	 */
+	public void setCredentialsProvider(CredentialsProvider credentialsProvider) {
+		this.credentialsProvider = credentialsProvider;
+	}
+
+	/**
+	 * @param tagOpt
+	 */
+	public void setTagOpt(TagOpt tagOpt) {
+		this.tagOpt = tagOpt;
+	}
+
+	/**
+	 * @param monitor
+	 * @throws InvocationTargetException
+	 */
+	public void run(IProgressMonitor monitor) throws InvocationTargetException {
+		if (operationResult != null)
+			throw new IllegalStateException(CoreText.OperationAlreadyExecuted);
+
+		IProgressMonitor actMonitor = monitor;
+		if (actMonitor == null)
+			actMonitor = new NullProgressMonitor();
+		EclipseGitProgressTransformer gitMonitor = new EclipseGitProgressTransformer(
+				actMonitor);
+		FetchCommand command;
+		if (rc == null)
+			command = new Git(repository).fetch().setRemote(
+					uri.toPrivateString()).setRefSpecs(specs);
+		else
+			command = new Git(repository).fetch().setRemote(rc.getName());
+		command.setCredentialsProvider(credentialsProvider).setTimeout(timeout)
+				.setDryRun(dryRun).setProgressMonitor(gitMonitor);
+		if (tagOpt != null)
+			command.setTagOpt(tagOpt);
+		try {
+			operationResult = command.call();
+		} catch (JGitInternalException e) {
+			throw new InvocationTargetException(e.getCause() != null ? e
+					.getCause() : e);
+		} catch (Exception e) {
+			throw new InvocationTargetException(e);
+		}
+	}
+
+	/**
+	 * @return the result, or <code>null</code> if the operation has not been
+	 *         executed
+	 */
+	public FetchResult getOperationResult() {
+		return operationResult;
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/FetchOperationResult.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/FetchOperationResult.java
new file mode 100644
index 0000000..2e2c868
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/FetchOperationResult.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Mathias Kinzler <mathias.kinzler@sap.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import org.eclipse.jgit.transport.FetchResult;
+import org.eclipse.jgit.transport.URIish;
+
+/**
+ * Stores the result of a fetch operation
+ */
+public class FetchOperationResult {
+	private final URIish uri;
+
+	private final FetchResult fetchResult;
+
+	private final String fetchErrorMessage;
+
+	/**
+	 * @param uri
+	 * @param result
+	 */
+	public FetchOperationResult(URIish uri, FetchResult result) {
+		this.uri = uri;
+		this.fetchResult = result;
+		this.fetchErrorMessage = null;
+	}
+
+	/**
+	 * @param uri
+	 * @param errorMessage
+	 */
+	public FetchOperationResult(URIish uri, String errorMessage) {
+		this.uri = uri;
+		this.fetchResult = null;
+		this.fetchErrorMessage = errorMessage;
+	}
+
+	/**
+	 * @return the URI
+	 *
+	 */
+	public URIish getURI() {
+		return uri;
+	}
+
+	/**
+	 * @return the result
+	 */
+	public FetchResult getFetchResult() {
+		return fetchResult;
+	}
+
+	/**
+	 * @return the error message
+	 */
+	public String getErrorMessage() {
+		return fetchErrorMessage;
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/GarbageCollectOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/GarbageCollectOperation.java
new file mode 100644
index 0000000..30decdd
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/GarbageCollectOperation.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (C) 2012, Matthias Sohn <matthias.sohn@sap.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import java.io.IOException;
+import java.text.ParseException;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.EclipseGitProgressTransformer;
+import org.eclipse.egit.core.internal.job.RuleUtil;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.internal.storage.file.FileRepository;
+import org.eclipse.jgit.internal.storage.file.GC;
+
+/**
+ * Operation to garbage collect a git repository
+ */
+public class GarbageCollectOperation implements IEGitOperation {
+
+	private Repository repository;
+
+	/**
+	 * @param repository the repository to garbage collect
+	 */
+	public GarbageCollectOperation(Repository repository) {
+		this.repository = repository;
+	}
+
+	/**
+	 * Execute garbage collection
+	 */
+	public void execute(IProgressMonitor monitor) throws CoreException {
+		GC gc = new GC((FileRepository) repository);
+		gc.setProgressMonitor(new EclipseGitProgressTransformer(
+				monitor));
+		try {
+			gc.gc();
+		} catch (IOException e) {
+			throw new CoreException(new Status(IStatus.ERROR,
+					Activator.getPluginId(), e.getMessage(), e));
+		} catch (ParseException e) {
+			throw new CoreException(new Status(IStatus.ERROR,
+					Activator.getPluginId(), e.getMessage(), e));
+		}
+	}
+
+	public ISchedulingRule getSchedulingRule() {
+		return RuleUtil.getRule(repository);
+	}
+
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/IEGitOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/IEGitOperation.java
new file mode 100644
index 0000000..ab6fa94
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/IEGitOperation.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Jens Baumgart <jens.baumgart@sap.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import org.eclipse.core.resources.IResourceRuleFactory;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.jgit.lib.Repository;
+
+/**
+ * interface for EGit operations
+ *
+ */
+public interface IEGitOperation {
+	/**
+	 * Executes the operation
+	 *
+	 * @param monitor
+	 *            a progress monitor, or <code>null</code> if progress reporting
+	 *            and cancellation are not desired
+	 * @throws CoreException
+	 */
+	void execute(IProgressMonitor monitor) throws CoreException;
+
+	/**
+	 * @return the rule needed to execute this operation.
+	 * <code>null</code> if no rule is required.
+	 * A rule is required if the operation changes resources.
+	 * It can also be useful to use a rule for reading resources to avoid
+	 * changes on the resources by other threads while the operation is running.
+	 * @see IResourceRuleFactory
+	 */
+	ISchedulingRule getSchedulingRule();
+
+	/**
+	 * A task to be performed before execution begins
+	 */
+	interface PreExecuteTask {
+
+		/**
+		 * Executes the task
+		 *
+		 * @param repository
+		 *            the git repository
+		 *
+		 * @param monitor
+		 *            a progress monitor, or <code>null</code> if progress
+		 *            reporting and cancellation are not desired
+		 * @throws CoreException
+		 */
+		void preExecute(Repository repository, IProgressMonitor monitor)
+				throws CoreException;
+	}
+
+	/**
+	 * A task to be performed after execution completes
+	 */
+	interface PostExecuteTask {
+
+		/**
+		 * Executes the task
+		 *
+		 * @param repository
+		 *            the git repository
+		 *
+		 * @param monitor
+		 *            a progress monitor, or <code>null</code> if progress
+		 *            reporting and cancellation are not desired
+		 * @throws CoreException
+		 */
+		void postExecute(Repository repository, IProgressMonitor monitor)
+				throws CoreException;
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/IgnoreOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/IgnoreOperation.java
new file mode 100644
index 0000000..2e1760a
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/IgnoreOperation.java
@@ -0,0 +1,222 @@
+/*******************************************************************************
+ * Copyright (C) 2009, Alex Blewitt <alex.blewitt@gmail.com>
+ * Copyright (C) 2010, Jens Baumgart <jens.baumgart@sap.com>
+ * Copyright (C) 2012, 2013 Robin Stocker <robin@nibor.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.CoreText;
+import org.eclipse.egit.core.internal.RepositoryUtil;
+import org.eclipse.egit.core.internal.job.RuleUtil;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * IgnoreOperation adds resources to a .gitignore file
+ *
+ */
+public class IgnoreOperation implements IEGitOperation {
+
+	private final Collection<IPath> paths;
+
+	private boolean gitignoreOutsideWSChanged;
+
+	private ISchedulingRule schedulingRule;
+
+	/**
+	 * construct an IgnoreOperation
+	 *
+	 * @param paths
+	 * @since 2.2
+	 */
+	public IgnoreOperation(Collection<IPath> paths) {
+		this.paths = paths;
+		gitignoreOutsideWSChanged = false;
+		schedulingRule = calcSchedulingRule();
+	}
+
+	/**
+	 * @param resources
+	 * @deprecated use {@link #IgnoreOperation(Collection)}
+	 */
+	@Deprecated
+	public IgnoreOperation(IResource[] resources) {
+		paths = new ArrayList<IPath>(resources.length);
+		for (IResource resource : resources) {
+			IPath location = resource.getLocation();
+			if (location != null)
+				paths.add(location);
+		}
+	}
+
+	public void execute(IProgressMonitor monitor) throws CoreException {
+		monitor.beginTask(CoreText.IgnoreOperation_taskName, paths.size());
+		try {
+			for (IPath path : paths) {
+				if (monitor.isCanceled())
+					break;
+				// TODO This is pretty inefficient; multiple ignores in
+				// the same directory cause multiple writes.
+
+				// NB This does the same thing in
+				// DecoratableResourceAdapter, but neither currently
+				// consult .gitignore
+				if (!RepositoryUtil.isIgnored(path))
+					addIgnore(monitor, path);
+				monitor.worked(1);
+			}
+			monitor.done();
+		} catch (CoreException e) {
+			throw e;
+		} catch (Exception e) {
+			throw new CoreException(Activator.error(
+					CoreText.IgnoreOperation_error, e));
+		}
+	}
+
+	/**
+	 * @return true if a gitignore file outside the workspace was changed. In
+	 *         this case the caller may need to perform manual UI refreshes
+	 *         because there was no ResourceChanged event.
+	 */
+	public boolean isGitignoreOutsideWSChanged() {
+		return gitignoreOutsideWSChanged;
+	}
+
+	public ISchedulingRule getSchedulingRule() {
+		return schedulingRule;
+	}
+
+	private void addIgnore(IProgressMonitor monitor, IPath path)
+			throws UnsupportedEncodingException, CoreException, IOException {
+		IPath parent = path.removeLastSegments(1);
+		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+		IContainer container = root.getContainerForLocation(parent);
+
+		String entry = "/" + path.lastSegment() + "\n"; //$NON-NLS-1$  //$NON-NLS-2$
+
+		if (container == null || container instanceof IWorkspaceRoot) {
+			Repository repository = RepositoryMapping.getMapping(
+					path).getRepository();
+			// .gitignore is not accessible as resource
+			IPath gitIgnorePath = parent.append(Constants.GITIGNORE_FILENAME);
+			IPath repoPath = new Path(repository.getWorkTree()
+					.getAbsolutePath());
+			if (!repoPath.isPrefixOf(gitIgnorePath)) {
+				String message = NLS.bind(
+						CoreText.IgnoreOperation_parentOutsideRepo,
+						path.toOSString(), repoPath.toOSString());
+				IStatus status = Activator.error(message, null);
+				throw new CoreException(status);
+			}
+			File gitIgnore = new File(gitIgnorePath.toOSString());
+			updateGitIgnore(gitIgnore, entry);
+			// no resource change event when updating .gitignore outside
+			// workspace => trigger manual decorator refresh
+			gitignoreOutsideWSChanged = true;
+		} else {
+			IFile gitignore = container.getFile(new Path(
+					Constants.GITIGNORE_FILENAME));
+			entry = getEntry(gitignore.getLocation().toFile(), entry);
+			IProgressMonitor subMonitor = new SubProgressMonitor(monitor, 1);
+			ByteArrayInputStream entryBytes = asStream(entry);
+			if (gitignore.exists())
+				gitignore.appendContents(entryBytes, true, true, subMonitor);
+			else
+				gitignore.create(entryBytes, true, subMonitor);
+		}
+	}
+
+	private boolean prependNewline(File file) throws IOException {
+		boolean prepend = false;
+		long length = file.length();
+		if (length > 0) {
+			RandomAccessFile raf = new RandomAccessFile(file, "r"); //$NON-NLS-1$
+			try {
+				// Read the last byte and see if it is a newline
+				ByteBuffer buffer = ByteBuffer.allocate(1);
+				FileChannel channel = raf.getChannel();
+				channel.position(length - 1);
+				if (channel.read(buffer) > 0) {
+					buffer.rewind();
+					prepend = buffer.get() != '\n';
+				}
+			} finally {
+				raf.close();
+			}
+		}
+		return prepend;
+	}
+
+	private String getEntry(File file, String entry) throws IOException {
+		return prependNewline(file) ? "\n" + entry : entry; //$NON-NLS-1$
+	}
+
+	private void updateGitIgnore(File gitIgnore, String entry)
+			throws CoreException {
+		try {
+			String ignoreLine = entry;
+			if (!gitIgnore.exists())
+				if (!gitIgnore.createNewFile()) {
+					String error = NLS.bind(
+							CoreText.IgnoreOperation_creatingFailed,
+							gitIgnore.getAbsolutePath());
+					throw new CoreException(Activator.error(error, null));
+				}
+			else
+				ignoreLine = getEntry(gitIgnore, ignoreLine);
+
+			FileOutputStream os = new FileOutputStream(gitIgnore, true);
+			try {
+				os.write(ignoreLine.getBytes());
+			} finally {
+				os.close();
+			}
+		} catch (IOException e) {
+			String error = NLS.bind(CoreText.IgnoreOperation_updatingFailed,
+					gitIgnore.getAbsolutePath());
+			throw new CoreException(Activator.error(error, e));
+		}
+	}
+
+	private ByteArrayInputStream asStream(String entry)
+			throws UnsupportedEncodingException {
+		return new ByteArrayInputStream(
+				entry.getBytes(Constants.CHARACTER_ENCODING));
+	}
+
+	private ISchedulingRule calcSchedulingRule() {
+		return RuleUtil.getRuleForContainers(paths);
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/ListRemoteOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/ListRemoteOperation.java
new file mode 100644
index 0000000..cacb9c4
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/ListRemoteOperation.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.com>
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.Collection;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.egit.core.internal.CoreText;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.LsRemoteCommand;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.api.errors.JGitInternalException;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.transport.CredentialsProvider;
+import org.eclipse.jgit.transport.URIish;
+
+/**
+ * Operation of listing remote repository advertised refs.
+ */
+public class ListRemoteOperation {
+	private final LsRemoteCommand rc;
+
+	private Collection<Ref> remoteRefs;
+
+	/**
+	 * Create listing operation for specified local repository (needed by
+	 * transport) and remote repository URI.
+	 *
+	 * @param localDb
+	 *            local repository (needed for transport) where fetch would
+	 *            occur.
+	 * @param uri
+	 *            URI of remote repository to list.
+	 * @param timeout
+	 *            timeout is seconds; 0 means no timeout
+	 */
+	public ListRemoteOperation(final Repository localDb, final URIish uri,
+			int timeout) {
+		Git git = new Git(localDb);
+		rc = git.lsRemote();
+		rc.setRemote(uri.toString()).setTimeout(timeout);
+	}
+
+	/**
+	 * @return collection of refs advertised by remote side.
+	 * @throws IllegalStateException
+	 *             if error occurred during earlier remote refs listing.
+	 */
+	public Collection<Ref> getRemoteRefs() {
+		checkState();
+		return remoteRefs;
+	}
+
+	/**
+	 * @param refName
+	 *            remote ref name to search for.
+	 * @return ref with specified refName or null if not found.
+	 * @throws IllegalStateException
+	 *             if error occurred during earlier remote refs listing.
+	 */
+	public Ref getRemoteRef(final String refName) {
+		checkState();
+		for (Ref r: remoteRefs)
+			if (r.getName().equals(refName))
+				return r;
+		return null;
+	}
+
+	/**
+	 * Sets a credentials provider
+	 * @param credentialsProvider
+	 */
+	public void setCredentialsProvider(CredentialsProvider credentialsProvider) {
+		rc.setCredentialsProvider(credentialsProvider);
+	}
+
+	/**
+	 * @param pm
+	 *            the monitor to be used for reporting progress and responding
+	 *            to cancellation. The monitor is never <code>null</code>
+	 * @throws InvocationTargetException
+	 * @throws InterruptedException
+	 */
+	public void run(IProgressMonitor pm) throws InvocationTargetException,
+			InterruptedException {
+		if (pm != null)
+			pm.beginTask(CoreText.ListRemoteOperation_title,
+					IProgressMonitor.UNKNOWN);
+		try {
+			remoteRefs = rc.call();
+		} catch (JGitInternalException e) {
+			throw new InvocationTargetException(e);
+		} catch (GitAPIException e) {
+			throw new InvocationTargetException(e);
+		}
+		if (pm != null)
+			pm.done();
+	}
+
+	private void checkState() {
+		if (remoteRefs == null)
+			throw new IllegalStateException(
+					"Error occurred during remote repo " +  //$NON-NLS-1$
+					"listing, no refs available"); //$NON-NLS-1$
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/MergeOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/MergeOperation.java
new file mode 100644
index 0000000..020efca
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/MergeOperation.java
@@ -0,0 +1,173 @@
+/*******************************************************************************
+ * Copyright (c) 2010 SAP AG.
+ * Copyright (C) 2012, 2013 Tomasz Zarna <tzarna@gmail.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Stefan Lay (SAP AG) - initial implementation
+ *    Tomasz Zarna (IBM) - merge squash, bug 382720
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import java.io.IOException;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.CoreText;
+import org.eclipse.egit.core.internal.util.ProjectUtil;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.MergeCommand;
+import org.eclipse.jgit.api.MergeCommand.FastForwardMode;
+import org.eclipse.jgit.api.MergeResult;
+import org.eclipse.jgit.api.errors.CheckoutConflictException;
+import org.eclipse.jgit.api.errors.ConcurrentRefUpdateException;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.api.errors.NoHeadException;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.merge.MergeStrategy;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.team.core.TeamException;
+
+/**
+ * This class implements the merge of a ref with the current head
+ *
+ */
+public class MergeOperation implements IEGitOperation {
+
+	private final Repository repository;
+
+	private final String refName;
+
+	private MergeStrategy mergeStrategy;
+
+	private boolean squash;
+
+	private FastForwardMode fastForwardMode;
+
+	private MergeResult mergeResult;
+
+	/**
+	 * @param repository
+	 * @param refName name of a commit which should be merged
+	 */
+	public MergeOperation(Repository repository, String refName) {
+		this.repository = repository;
+		this.refName = refName;
+	}
+
+	/**
+	* Create a MergeOperation object
+	* @param repository
+	* @param refName name of a commit which should be merged
+	* @param mergeStrategy the strategy to use for merge
+	*/
+	public MergeOperation(Repository repository, String refName,
+		String mergeStrategy) {
+		this.repository = repository;
+		this.refName = refName;
+		if (mergeStrategy != null)
+			this.mergeStrategy = MergeStrategy.get(mergeStrategy);
+	}
+
+	/**
+	 * @param squash true to squash merge commits
+	 */
+	public void setSquash(boolean squash) {
+		this.squash = squash;
+	}
+
+	/**
+	 * @param ffmode set the fast forward mode
+	 */
+	public void setFastForwardMode(FastForwardMode ffmode) {
+		this.fastForwardMode = ffmode;
+	}
+
+	public void execute(IProgressMonitor m) throws CoreException {
+		if (mergeResult != null)
+			throw new CoreException(new Status(IStatus.ERROR, Activator
+					.getPluginId(), CoreText.OperationAlreadyExecuted));
+		IProgressMonitor monitor;
+		if (m == null)
+			monitor = new NullProgressMonitor();
+		else
+			monitor = m;
+		IWorkspaceRunnable action = new IWorkspaceRunnable() {
+
+			public void run(IProgressMonitor mymonitor) throws CoreException {
+				IProject[] validProjects = ProjectUtil.getValidOpenProjects(repository);
+				mymonitor.beginTask(NLS.bind(CoreText.MergeOperation_ProgressMerge, refName), 3);
+				Git git = new Git(repository);
+				mymonitor.worked(1);
+				MergeCommand merge;
+				try {
+					FastForwardMode ffmode = fastForwardMode;
+					if (ffmode == null)
+						ffmode = Activator.getDefault().getRepositoryUtil()
+								.getFastForwardMode(repository);
+					Ref ref = repository.getRef(refName);
+					if (ref != null)
+						merge = git.merge().include(ref).setFastForward(ffmode);
+					else
+						merge = git.merge()
+								.include(ObjectId.fromString(refName))
+								.setFastForward(ffmode);
+				} catch (IOException e) {
+					throw new TeamException(CoreText.MergeOperation_InternalError, e);
+				}
+				merge.setSquash(squash);
+				if (mergeStrategy != null) {
+					merge.setStrategy(mergeStrategy);
+				}
+				try {
+					mergeResult = merge.call();
+					mymonitor.worked(1);
+					if (MergeResult.MergeStatus.NOT_SUPPORTED.equals(mergeResult.getMergeStatus()))
+						throw new TeamException(new Status(IStatus.INFO, Activator.getPluginId(), mergeResult.toString()));
+				} catch (NoHeadException e) {
+					throw new TeamException(CoreText.MergeOperation_MergeFailedNoHead, e);
+				} catch (ConcurrentRefUpdateException e) {
+					throw new TeamException(CoreText.MergeOperation_MergeFailedRefUpdate, e);
+				} catch (CheckoutConflictException e) {
+					mergeResult = new MergeResult(e.getConflictingPaths());
+					return;
+				} catch (GitAPIException e) {
+					throw new TeamException(e.getLocalizedMessage(), e.getCause());
+				} finally {
+					ProjectUtil.refreshValidProjects(validProjects, new SubProgressMonitor(
+							mymonitor, 1));
+					mymonitor.done();
+				}
+			}
+		};
+		// lock workspace to protect working tree changes
+		ResourcesPlugin.getWorkspace().run(action, monitor);
+	}
+
+	/**
+	 * @return the merge result, or <code>null</code> if this has not been
+	 *         executed or if an exception occurred
+	 */
+	public MergeResult getResult() {
+		return this.mergeResult;
+	}
+
+	public ISchedulingRule getSchedulingRule() {
+		return ResourcesPlugin.getWorkspace().getRoot();
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/PullOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/PullOperation.java
new file mode 100644
index 0000000..4a4be59
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/PullOperation.java
@@ -0,0 +1,145 @@
+/*******************************************************************************
+ * Copyright (c) 2010 SAP AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Mathias Kinzler <mathias.kinzler@sap.com> - initial implementation
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.CoreText;
+import org.eclipse.egit.core.internal.EclipseGitProgressTransformer;
+import org.eclipse.egit.core.internal.util.ProjectUtil;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.MergeResult;
+import org.eclipse.jgit.api.MergeResult.MergeStatus;
+import org.eclipse.jgit.api.PullCommand;
+import org.eclipse.jgit.api.PullResult;
+import org.eclipse.jgit.api.errors.DetachedHeadException;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.api.errors.InvalidConfigurationException;
+import org.eclipse.jgit.api.errors.JGitInternalException;
+import org.eclipse.jgit.errors.TransportException;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Wraps the JGit API {@link PullCommand} into an operation
+ */
+public class PullOperation implements IEGitOperation {
+	private final Repository[] repositories;
+
+	private final Map<Repository, Object> results = new LinkedHashMap<Repository, Object>();
+
+	private final int timeout;
+
+	/**
+	 * @param repositories
+	 *            the repository
+	 * @param timeout
+	 *            in seconds
+	 */
+	public PullOperation(Set<Repository> repositories, int timeout) {
+		this.timeout = timeout;
+		this.repositories = repositories.toArray(new Repository[repositories
+				.size()]);
+	}
+
+	public void execute(IProgressMonitor m) throws CoreException {
+		if (!results.isEmpty())
+			throw new CoreException(new Status(IStatus.ERROR, Activator
+					.getPluginId(), CoreText.OperationAlreadyExecuted));
+		IProgressMonitor monitor;
+		if (m == null)
+			monitor = new NullProgressMonitor();
+		else
+			monitor = m;
+		monitor.beginTask(NLS.bind(CoreText.PullOperation_TaskName, Integer
+				.valueOf(repositories.length)), repositories.length * 2);
+		IWorkspaceRunnable action = new IWorkspaceRunnable() {
+			public void run(IProgressMonitor mymonitor) throws CoreException {
+				for (int i = 0; i < repositories.length; i++) {
+					Repository repository = repositories[i];
+					if (mymonitor.isCanceled())
+						throw new CoreException(Status.CANCEL_STATUS);
+					IProject[] validProjects = ProjectUtil.getValidOpenProjects(repository);
+					PullCommand pull = new Git(repository).pull();
+					PullResult pullResult = null;
+					try {
+						pull.setProgressMonitor(new EclipseGitProgressTransformer(
+								new SubProgressMonitor(mymonitor, 1)));
+						pull.setTimeout(timeout);
+						pullResult = pull.call();
+						results.put(repository, pullResult);
+					} catch (DetachedHeadException e) {
+						results.put(repository, Activator.error(
+								CoreText.PullOperation_DetachedHeadMessage, e));
+					} catch (InvalidConfigurationException e) {
+						IStatus error = Activator
+								.error(CoreText.PullOperation_PullNotConfiguredMessage,
+										e);
+						results.put(repository, error);
+					} catch (GitAPIException e) {
+						results.put(repository,
+								Activator.error(e.getMessage(), e));
+					} catch (JGitInternalException e) {
+						Throwable cause = e.getCause();
+						if (cause == null || !(cause instanceof TransportException))
+							cause = e;
+						results.put(repository,
+								Activator.error(cause.getMessage(), cause));
+					} finally {
+						mymonitor.worked(1);
+						if (refreshNeeded(pullResult)) {
+							ProjectUtil.refreshValidProjects(validProjects,
+									new SubProgressMonitor(mymonitor, 1));
+							mymonitor.worked(1);
+						}
+					}
+				}
+			}
+		};
+		// lock workspace to protect working tree changes
+		ResourcesPlugin.getWorkspace().run(action, monitor);
+	}
+
+	private boolean refreshNeeded(PullResult pullResult) {
+		if (pullResult == null)
+			return true;
+		MergeResult mergeResult = pullResult.getMergeResult();
+		if (mergeResult == null)
+			return true;
+		if (mergeResult.getMergeStatus() == MergeStatus.ALREADY_UP_TO_DATE)
+			return false;
+		return true;
+	}
+
+	/**
+	 * @return the results, or an empty Map if this has not been executed
+	 */
+	public Map<Repository, Object> getResults() {
+		return this.results;
+	}
+
+	public ISchedulingRule getSchedulingRule() {
+		return ResourcesPlugin.getWorkspace().getRoot();
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/PushOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/PushOperation.java
new file mode 100644
index 0000000..9c4080d
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/PushOperation.java
@@ -0,0 +1,262 @@
+/*******************************************************************************
+ * Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.com>
+ * Copyright (C) 2011, Mathias Kinzler <mathias.kinzler@sap.com>
+ * Copyright (C) 2012, Robin Stocker <robin@nibor.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import java.lang.reflect.InvocationTargetException;
+import java.net.URISyntaxException;
+import java.util.Collection;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.CoreText;
+import org.eclipse.egit.core.internal.EclipseGitProgressTransformer;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.JGitInternalException;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.transport.CredentialsProvider;
+import org.eclipse.jgit.transport.PushResult;
+import org.eclipse.jgit.transport.RemoteConfig;
+import org.eclipse.jgit.transport.RemoteRefUpdate;
+import org.eclipse.jgit.transport.RemoteRefUpdate.Status;
+import org.eclipse.jgit.transport.Transport;
+import org.eclipse.jgit.transport.URIish;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Push operation: pushing from local repository to one or many remote ones.
+ */
+public class PushOperation {
+	private static final int WORK_UNITS_PER_TRANSPORT = 10;
+
+	private final Repository localDb;
+
+	private final PushOperationSpecification specification;
+
+	private final boolean dryRun;
+
+	private final String remoteName;
+
+	private final int timeout;
+
+	private PushOperationResult operationResult;
+
+	private CredentialsProvider credentialsProvider;
+
+	/**
+	 * Create push operation for provided specification.
+	 *
+	 * @param localDb
+	 *            local repository.
+	 * @param specification
+	 *            specification of ref updates for remote repositories.
+	 * @param dryRun
+	 *            true if push operation should just check for possible result
+	 *            and not really update remote refs, false otherwise - when push
+	 *            should act normally.
+	 * @param timeout
+	 *            the timeout in seconds (0 for no timeout)
+	 */
+	public PushOperation(final Repository localDb,
+			final PushOperationSpecification specification,
+			final boolean dryRun, int timeout) {
+		this.localDb = localDb;
+		this.specification = specification;
+		this.dryRun = dryRun;
+		this.remoteName = null;
+		this.timeout = timeout;
+	}
+
+	/**
+	 * Creates a push operation for a remote configuration.
+	 *
+	 * @param localDb
+	 * @param remoteName
+	 * @param dryRun
+	 * @param timeout
+	 */
+	public PushOperation(final Repository localDb, final String remoteName,
+			final boolean dryRun, int timeout) {
+		this.localDb = localDb;
+		this.specification = null;
+		this.dryRun = dryRun;
+		this.remoteName = remoteName;
+		this.timeout = timeout;
+	}
+
+	/**
+	 * @param credentialsProvider
+	 */
+	public void setCredentialsProvider(CredentialsProvider credentialsProvider) {
+		this.credentialsProvider = credentialsProvider;
+	}
+
+	/**
+	 * @return push operation result
+	 */
+	public PushOperationResult getOperationResult() {
+		if (operationResult == null)
+			throw new IllegalStateException(CoreText.OperationNotYetExecuted);
+		return operationResult;
+	}
+
+	/**
+	 * @return operation specification, as provided in constructor (may be
+	 *         <code>null</code>)
+	 */
+	public PushOperationSpecification getSpecification() {
+		return specification;
+	}
+
+	/**
+	 * @param actMonitor
+	 *            may be <code>null</code> if progress monitoring is not desired
+	 * @throws InvocationTargetException
+	 *             not really used: failure is communicated via the result (see
+	 *             {@link #getOperationResult()})
+	 */
+	public void run(IProgressMonitor actMonitor)
+			throws InvocationTargetException {
+
+		if (operationResult != null)
+			throw new IllegalStateException(CoreText.OperationAlreadyExecuted);
+
+		if (this.specification != null)
+			for (URIish uri : this.specification.getURIs()) {
+				for (RemoteRefUpdate update : this.specification
+						.getRefUpdates(uri))
+					if (update.getStatus() != Status.NOT_ATTEMPTED)
+						throw new IllegalStateException(
+								CoreText.RemoteRefUpdateCantBeReused);
+			}
+		IProgressMonitor monitor;
+		if (actMonitor == null)
+			monitor = new NullProgressMonitor();
+		else
+			monitor = actMonitor;
+
+		final int totalWork;
+		if (specification != null)
+			totalWork = specification.getURIsNumber()
+					* WORK_UNITS_PER_TRANSPORT;
+		else
+			totalWork = 1;
+		if (dryRun)
+			monitor.beginTask(CoreText.PushOperation_taskNameDryRun, totalWork);
+		else
+			monitor.beginTask(CoreText.PushOperation_taskNameNormalRun,
+					totalWork);
+
+		operationResult = new PushOperationResult();
+		Git git = new Git(localDb);
+
+		if (specification != null)
+			for (final URIish uri : specification.getURIs()) {
+				final SubProgressMonitor subMonitor = new SubProgressMonitor(
+						monitor, WORK_UNITS_PER_TRANSPORT,
+						SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK);
+
+				try {
+					if (monitor.isCanceled()) {
+						operationResult.addOperationResult(uri,
+								CoreText.PushOperation_resultCancelled);
+						continue;
+					}
+
+					Collection<RemoteRefUpdate> refUpdates = specification.getRefUpdates(uri);
+					final EclipseGitProgressTransformer gitSubMonitor = new EclipseGitProgressTransformer(
+							subMonitor);
+
+					try {
+						Transport transport = Transport.open(localDb, uri);
+						transport.setDryRun(dryRun);
+						transport.setTimeout(timeout);
+						if (credentialsProvider != null)
+							transport.setCredentialsProvider(credentialsProvider);
+						PushResult result = transport.push(gitSubMonitor, refUpdates);
+
+						operationResult.addOperationResult(result.getURI(), result);
+						specification.addURIRefUpdates(result.getURI(), result.getRemoteUpdates());
+					} catch (JGitInternalException e) {
+						String errorMessage = e.getCause() != null ? e
+								.getCause().getMessage() : e.getMessage();
+						String userMessage = NLS.bind(
+										CoreText.PushOperation_InternalExceptionOccurredMessage,
+										errorMessage);
+						handleException(uri, e, userMessage);
+					} catch (Exception e) {
+						handleException(uri, e, e.getMessage());
+					}
+
+					monitor.worked(WORK_UNITS_PER_TRANSPORT);
+				} finally {
+					// Dirty trick to get things always working.
+					subMonitor.beginTask("", WORK_UNITS_PER_TRANSPORT); //$NON-NLS-1$
+					subMonitor.done();
+					subMonitor.done();
+				}
+			}
+		else {
+			final EclipseGitProgressTransformer gitMonitor = new EclipseGitProgressTransformer(
+					monitor);
+			try {
+				Iterable<PushResult> results = git.push().setRemote(
+						remoteName).setDryRun(dryRun).setTimeout(timeout)
+						.setProgressMonitor(gitMonitor).setCredentialsProvider(
+								credentialsProvider).call();
+				for (PushResult result : results) {
+					operationResult.addOperationResult(result.getURI(), result);
+				}
+			} catch (JGitInternalException e) {
+				String errorMessage = e.getCause() != null ? e.getCause()
+						.getMessage() : e.getMessage();
+				String userMessage = NLS.bind(
+						CoreText.PushOperation_InternalExceptionOccurredMessage,
+						errorMessage);
+				URIish uri = getPushURIForErrorHandling();
+				handleException(uri, e, userMessage);
+			} catch (Exception e) {
+				URIish uri = getPushURIForErrorHandling();
+				handleException(uri, e, e.getMessage());
+			}
+		}
+		monitor.done();
+	}
+
+	private void handleException(final URIish uri, Exception e,
+			String userMessage) {
+		String uriString;
+		if (uri != null) {
+			operationResult.addOperationResult(uri, userMessage);
+			uriString = uri.toString();
+		} else
+			uriString = "retrieving URI failed"; //$NON-NLS-1$
+
+		String userMessageForUri = NLS.bind(
+				CoreText.PushOperation_ExceptionOccurredDuringPushOnUriMessage,
+				uriString, userMessage);
+		Activator.logError(userMessageForUri, e);
+	}
+
+	private URIish getPushURIForErrorHandling() {
+		RemoteConfig rc = null;
+		try {
+			rc = new RemoteConfig(localDb.getConfig(), remoteName);
+			return rc.getPushURIs().isEmpty() ? rc.getURIs().get(0) : rc
+					.getPushURIs().get(0);
+		} catch (URISyntaxException e) {
+			// should not happen
+			Activator.logError("Reading RemoteConfig failed", e); //$NON-NLS-1$
+			return null;
+		}
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/PushOperationResult.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/PushOperationResult.java
new file mode 100644
index 0000000..cadf1e5
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/PushOperationResult.java
@@ -0,0 +1,282 @@
+/*******************************************************************************
+ * Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Set;
+
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.transport.PushResult;
+import org.eclipse.jgit.transport.RemoteRefUpdate;
+import org.eclipse.jgit.transport.URIish;
+
+/**
+ * Data class for storing push operation results for each remote repository/URI
+ * being part of push operation.
+ * <p>
+ * One instance of this class is dedicated for result of one push operation:
+ * either to one URI or to many URIs.
+ *
+ * @see PushOperation
+ */
+public class PushOperationResult {
+	private LinkedHashMap<URIish, Entry> urisEntries;
+
+	/**
+	 * Construct empty push operation result.
+	 */
+	public PushOperationResult() {
+		this.urisEntries = new LinkedHashMap<URIish, Entry>();
+	}
+
+	/**
+	 * Add push result for the repository (URI) with successful connection.
+	 *
+	 * @param uri
+	 *            remote repository URI.
+	 * @param result
+	 *            push result.
+	 */
+	public void addOperationResult(final URIish uri, final PushResult result) {
+		urisEntries.put(uri, new Entry(result));
+	}
+
+	/**
+	 * Add error message for the repository (URI) with unsuccessful connection.
+	 *
+	 * @param uri
+	 *            remote repository URI.
+	 * @param errorMessage
+	 *            failure error message.
+	 */
+	public void addOperationResult(final URIish uri, final String errorMessage) {
+		urisEntries.put(uri, new Entry(errorMessage));
+	}
+
+	/**
+	 * @return set of remote repositories URIish. Set is ordered in addition
+	 *         sequence, which is usually the same as that from
+	 *         {@link PushOperationSpecification}.
+	 */
+	public Set<URIish> getURIs() {
+		return Collections.unmodifiableSet(urisEntries.keySet());
+	}
+
+	/**
+	 * @param uri
+	 *            remote repository URI.
+	 * @return true if connection was successful for this repository (URI),
+	 *         false if this operation ended with unsuccessful connection.
+	 */
+	public boolean isSuccessfulConnection(final URIish uri) {
+		return urisEntries.get(uri).isSuccessfulConnection();
+	}
+
+	/**
+	 * @return true if connection was successful for any repository (URI), false
+	 *         otherwise.
+	 */
+	public boolean isSuccessfulConnectionForAnyURI() {
+		for (final URIish uri : getURIs()) {
+			if (isSuccessfulConnection(uri))
+				return true;
+		}
+		return false;
+	}
+
+	/**
+	 * @param uri
+	 *            remote repository URI.
+	 * @return push result for this repository (URI) or null if operation ended
+	 *         with unsuccessful connection for this URI.
+	 */
+	public PushResult getPushResult(final URIish uri) {
+		return urisEntries.get(uri).getResult();
+	}
+
+	/**
+	 * @param uri
+	 *            remote repository URI.
+	 * @return error message for this repository (URI) or null if operation
+	 *         ended with successful connection for this URI.
+	 */
+	public String getErrorMessage(final URIish uri) {
+		return urisEntries.get(uri).getErrorMessage();
+	}
+
+	/**
+	 * @return string being list of failed URIs with their error messages.
+	 */
+	public String getErrorStringForAllURis() {
+		final StringBuilder sb = new StringBuilder();
+		boolean first = true;
+		for (final URIish uri : getURIs()) {
+			if (first)
+				first = false;
+			else
+				sb.append(", ");  //$NON-NLS-1$
+			sb.append(uri);
+			sb.append(" (");  //$NON-NLS-1$
+			sb.append(getErrorMessage(uri));
+			sb.append(")"); //$NON-NLS-1$
+		}
+		return sb.toString();
+	}
+
+	/**
+	 * Derive push operation specification from this push operation result.
+	 * <p>
+	 * Specification is created basing on URIs of remote repositories in this
+	 * result that completed without connection errors, and remote ref updates
+	 * from push results.
+	 * <p>
+	 * This method is targeted to provide support for 2-stage push, where first
+	 * operation is dry run for user confirmation and second one is a real
+	 * operation.
+	 *
+	 * @param requireUnchanged
+	 *            if true, newly created copies of remote ref updates have
+	 *            expected old object id set to previously advertised ref value
+	 *            (remote ref won't be updated if it change in the mean time),
+	 *            if false, newly create copies of remote ref updates have
+	 *            expected object id set up as in this result source
+	 *            specification.
+	 * @return derived specification for another push operation.
+	 * @throws IOException
+	 *             when some previously locally available source ref is not
+	 *             available anymore, or some error occurred during creation
+	 *             locally tracking ref update.
+	 *
+	 */
+	public PushOperationSpecification deriveSpecification(
+			final boolean requireUnchanged) throws IOException {
+		final PushOperationSpecification spec = new PushOperationSpecification();
+		for (final URIish uri : getURIs()) {
+			final PushResult pr = getPushResult(uri);
+			if (pr == null)
+				continue;
+
+			final Collection<RemoteRefUpdate> oldUpdates = pr
+					.getRemoteUpdates();
+			final ArrayList<RemoteRefUpdate> newUpdates = new ArrayList<RemoteRefUpdate>(
+					oldUpdates.size());
+			for (final RemoteRefUpdate rru : oldUpdates) {
+				final ObjectId expectedOldObjectId;
+				if (requireUnchanged) {
+					final Ref advertisedRef = getPushResult(uri)
+							.getAdvertisedRef(rru.getRemoteName());
+					if (advertisedRef == null)
+						expectedOldObjectId = ObjectId.zeroId();
+					else
+						expectedOldObjectId = advertisedRef.getObjectId();
+				} else
+					expectedOldObjectId = rru.getExpectedOldObjectId();
+				final RemoteRefUpdate newRru = new RemoteRefUpdate(rru,
+						expectedOldObjectId);
+				newUpdates.add(newRru);
+			}
+			spec.addURIRefUpdates(uri, newUpdates);
+		}
+		return spec;
+	}
+
+	/**
+	 * This implementation returns true if all following conditions are met:
+	 * <ul>
+	 * <li>both objects result have the same set successfully connected
+	 * repositories (URIs) - unsuccessful connections are discarded, AND <li>
+	 * remote ref updates must match for each successful connection in sense of
+	 * equal remoteName, equal status and equal newObjectId value.</li>
+	 * </ul>
+	 *
+	 * @see Object#equals(Object)
+	 * @param obj
+	 *            other push operation result to compare to.
+	 * @return true if object is equal to this one in terms of conditions
+	 *         described above, false otherwise.
+	 */
+	@Override
+	public boolean equals(final Object obj) {
+		if (obj == this)
+			return true;
+
+		if (!(obj instanceof PushOperationResult))
+			return false;
+
+		final PushOperationResult other = (PushOperationResult) obj;
+
+		// Check successful connections/URIs two-ways:
+		final Set<URIish> otherURIs = other.getURIs();
+		for (final URIish uri : getURIs()) {
+			if (isSuccessfulConnection(uri)
+					&& (!otherURIs.contains(uri) || !other
+							.isSuccessfulConnection(uri)))
+				return false;
+		}
+		for (final URIish uri : other.getURIs()) {
+			if (other.isSuccessfulConnection(uri)
+					&& (!urisEntries.containsKey(uri) || !isSuccessfulConnection(uri)))
+				return false;
+		}
+
+		for (final URIish uri : getURIs()) {
+			if (!isSuccessfulConnection(uri))
+				continue;
+
+			final PushResult otherPushResult = other.getPushResult(uri);
+			for (final RemoteRefUpdate rru : getPushResult(uri)
+					.getRemoteUpdates()) {
+				final RemoteRefUpdate otherRru = otherPushResult
+						.getRemoteUpdate(rru.getRemoteName());
+				if (otherRru == null)
+					return false;
+				if (otherRru.getStatus() != rru.getStatus()
+						|| otherRru.getNewObjectId() != rru.getNewObjectId())
+					return false;
+			}
+		}
+		return true;
+	}
+
+	@Override
+	public int hashCode() {
+		return urisEntries.hashCode();
+	}
+
+	private static class Entry {
+		private String errorMessage;
+
+		private PushResult result;
+
+		Entry(final PushResult result) {
+			this.result = result;
+		}
+
+		Entry(final String errorMessage) {
+			this.errorMessage = errorMessage;
+		}
+
+		boolean isSuccessfulConnection() {
+			return result != null;
+		}
+
+		String getErrorMessage() {
+			return errorMessage;
+		}
+
+		PushResult getResult() {
+			return result;
+		}
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/PushOperationSpecification.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/PushOperationSpecification.java
new file mode 100644
index 0000000..3982b93
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/PushOperationSpecification.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Set;
+
+import org.eclipse.jgit.transport.RemoteRefUpdate;
+import org.eclipse.jgit.transport.URIish;
+
+/**
+ * Data class storing push operation update specifications for each remote
+ * repository.
+ * <p>
+ * One instance is dedicated for one push operation: either push to one URI or
+ * to many URIs.
+ *
+ * @see PushOperation
+ */
+public class PushOperationSpecification {
+	private LinkedHashMap<URIish, Collection<RemoteRefUpdate>> urisRefUpdates;
+
+	/**
+	 * Create empty instance of specification.
+	 * <p>
+	 * URIs and ref updates should be configured
+	 * {@link #addURIRefUpdates(URIish, Collection)} method.
+	 */
+	public PushOperationSpecification() {
+		this.urisRefUpdates = new LinkedHashMap<URIish, Collection<RemoteRefUpdate>>();
+	}
+
+	/**
+	 * Add remote repository URI with ref updates specification.
+	 * <p>
+	 * Ref updates are not in constructor - pay attention to not share them
+	 * between different URIs ref updates or push operations.
+	 * <p>
+	 * Note that refUpdates can differ between URIs <b>only</b> by expected old
+	 * object id field: {@link RemoteRefUpdate#getExpectedOldObjectId()}.
+	 *
+	 * @param uri
+	 *            remote repository URI.
+	 * @param refUpdates
+	 *            collection of remote ref updates specifications.
+	 */
+	public void addURIRefUpdates(final URIish uri,
+			Collection<RemoteRefUpdate> refUpdates) {
+		urisRefUpdates.put(uri, refUpdates);
+	}
+
+	/**
+	 * @return set of remote repositories URIish. Set is ordered in addition
+	 *         sequence.
+	 */
+	public Set<URIish> getURIs() {
+		return Collections.unmodifiableSet(urisRefUpdates.keySet());
+	}
+
+	/**
+	 * @return number of remote repositories URI for this push operation.
+	 */
+	public int getURIsNumber() {
+		return urisRefUpdates.keySet().size();
+	}
+
+	/**
+	 * @param uri
+	 *            remote repository URI.
+	 * @return remote ref updates as specified by user for this URI.
+	 */
+	public Collection<RemoteRefUpdate> getRefUpdates(final URIish uri) {
+		return Collections.unmodifiableCollection(urisRefUpdates.get(uri));
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/RebaseOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/RebaseOperation.java
new file mode 100644
index 0000000..a0638b8
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/RebaseOperation.java
@@ -0,0 +1,141 @@
+/*******************************************************************************
+ * Copyright (c) 2010 SAP AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Mathias Kinzler <mathias.kinzler@sap.com> - initial implementation
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.CoreText;
+import org.eclipse.egit.core.internal.EclipseGitProgressTransformer;
+import org.eclipse.egit.core.internal.util.ProjectUtil;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.RebaseCommand;
+import org.eclipse.jgit.api.RebaseResult;
+import org.eclipse.jgit.api.RebaseCommand.Operation;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.api.errors.JGitInternalException;
+import org.eclipse.jgit.api.errors.NoHeadException;
+import org.eclipse.jgit.api.errors.RefNotFoundException;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.Repository;
+
+/**
+ * This class implements rebase.
+ */
+public class RebaseOperation implements IEGitOperation {
+	private final Repository repository;
+
+	private final Ref ref;
+
+	private final Operation operation;
+
+	private RebaseResult result;
+
+	/**
+	 * Construct a {@link RebaseOperation} object for a {@link Ref}.
+	 * <p>
+	 * Upon {@link #execute(IProgressMonitor)}, the current HEAD will be rebased
+	 * onto the provided {@link Ref}
+	 *
+	 * @param repository
+	 *            the {@link Repository}
+	 * @param ref
+	 *            the branch or tag
+	 */
+	public RebaseOperation(Repository repository, Ref ref) {
+		this.repository = repository;
+		this.operation = Operation.BEGIN;
+		this.ref = ref;
+	}
+
+	/**
+	 * Used to abort, skip, or continue a stopped rebase operation that has been
+	 * started before.
+	 *
+	 * @param repository
+	 *            the {@link Repository}
+	 * @param operation
+	 *            one of {@link Operation#ABORT}, {@link Operation#CONTINUE},
+	 *            {@link Operation#SKIP}
+	 */
+	public RebaseOperation(Repository repository, Operation operation) {
+		this.repository = repository;
+		this.operation = operation;
+		this.ref = null;
+	}
+
+	public void execute(IProgressMonitor m) throws CoreException {
+		if (result != null)
+			throw new CoreException(new Status(IStatus.ERROR, Activator
+					.getPluginId(), CoreText.OperationAlreadyExecuted));
+		IProgressMonitor monitor;
+		if (m == null)
+			monitor = new NullProgressMonitor();
+		else
+			monitor = m;
+		final IProject[] validProjects = ProjectUtil.getValidOpenProjects(repository);
+		IWorkspaceRunnable action = new IWorkspaceRunnable() {
+			public void run(IProgressMonitor actMonitor) throws CoreException {
+				RebaseCommand cmd = new Git(repository).rebase()
+						.setProgressMonitor(
+								new EclipseGitProgressTransformer(actMonitor));
+				try {
+					if (operation == Operation.BEGIN)
+						result = cmd.setUpstream(ref.getName()).call();
+					else
+						result = cmd.setOperation(operation).call();
+
+				} catch (NoHeadException e) {
+					throw new CoreException(Activator.error(e.getMessage(), e));
+				} catch (RefNotFoundException e) {
+					throw new CoreException(Activator.error(e.getMessage(), e));
+				} catch (JGitInternalException e) {
+					throw new CoreException(Activator.error(e.getMessage(), e));
+				} catch (GitAPIException e) {
+					throw new CoreException(Activator.error(e.getMessage(), e));
+				} finally {
+					if (refreshNeeded())
+						ProjectUtil.refreshValidProjects(validProjects,
+								new SubProgressMonitor(actMonitor, 1));
+				}
+			}
+		};
+		ResourcesPlugin.getWorkspace().run(action, monitor);
+	}
+
+	private boolean refreshNeeded() {
+		if (result == null)
+			return true;
+		if (result.getStatus() == RebaseResult.Status.UP_TO_DATE)
+			return false;
+		return true;
+	}
+
+	public ISchedulingRule getSchedulingRule() {
+		return ResourcesPlugin.getWorkspace().getRoot();
+	}
+
+	/**
+	 * @return the result of calling {@link #execute(IProgressMonitor)}, or
+	 *         <code>null</code> if this has not been executed yet
+	 */
+	public RebaseResult getResult() {
+		return result;
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/RemoveFromIndexOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/RemoveFromIndexOperation.java
new file mode 100644
index 0000000..dca6b54
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/RemoveFromIndexOperation.java
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * Copyright (C) 2011, Bernard Leach <leachbj@bouncycastle.org>
+ * Copyright (C) 2011, Dariusz Luksza <dariusz@luksza.org>
+ * Copyright (C) 2012, Robin Stocker <robin@nibor.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import static org.eclipse.egit.core.internal.project.RepositoryMapping.findRepositoryMapping;
+import static org.eclipse.jgit.lib.Constants.HEAD;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Map;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.CoreText;
+import org.eclipse.egit.core.internal.job.RuleUtil;
+import org.eclipse.egit.core.internal.util.ResourceUtil;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.GitCommand;
+import org.eclipse.jgit.api.ResetCommand;
+import org.eclipse.jgit.api.RmCommand;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.Repository;
+
+/**
+ * Remove from Git Index operation (unstage).
+ */
+public class RemoveFromIndexOperation implements IEGitOperation {
+
+	private final Map<Repository, Collection<String>> pathsByRepository;
+
+	/**
+	 * @param paths
+	 *            list of paths that should be removed from index
+	 * @since 2.2
+	 */
+	public RemoveFromIndexOperation(Collection<IPath> paths) {
+		this.pathsByRepository = ResourceUtil.splitPathsByRepository(paths);
+	}
+
+	/**
+	 * @param repo
+	 *            repository in with given files should be removed from index
+	 * @param resources
+	 *            list of resources that should be removed from index
+	 * @deprecated use {@link #RemoveFromIndexOperation(Collection)} instead
+	 */
+	@Deprecated
+	public RemoveFromIndexOperation(Repository repo, IResource[] resources) {
+		this.pathsByRepository = ResourceUtil.splitResourcesByRepository(resources);
+	}
+
+	public void execute(IProgressMonitor m) throws CoreException {
+		IProgressMonitor monitor = (m != null) ? m : new NullProgressMonitor();
+
+		monitor.beginTask(
+				CoreText.RemoveFromIndexOperation_removingFilesFromIndex,
+				pathsByRepository.size());
+
+		for (Map.Entry<Repository, Collection<String>> entry : pathsByRepository.entrySet()) {
+			Repository repository = entry.getKey();
+			Collection<String> paths = entry.getValue();
+
+			GitCommand<?> command = prepareCommand(repository, paths);
+
+			try {
+				command.call();
+				monitor.worked(1);
+			} catch (GitAPIException e) {
+				Activator.logError(e.getMessage(), e);
+			} finally {
+				findRepositoryMapping(repository).fireRepositoryChanged();
+			}
+		}
+
+		monitor.done();
+	}
+
+	public ISchedulingRule getSchedulingRule() {
+		return RuleUtil.getRuleForRepositories(pathsByRepository.keySet());
+	}
+
+	private static GitCommand<?> prepareCommand(Repository repository,
+			Collection<String> paths) {
+		Git git = new Git(repository);
+		if (hasHead(repository)) {
+			ResetCommand resetCommand = git.reset();
+			resetCommand.setRef(HEAD);
+			for (String path : paths)
+				resetCommand.addPath(getCommandPath(path));
+			return resetCommand;
+		} else {
+			RmCommand rmCommand = git.rm();
+			rmCommand.setCached(true);
+			for (String path : paths)
+				rmCommand.addFilepattern(getCommandPath(path));
+			return rmCommand;
+		}
+	}
+
+	private static boolean hasHead(Repository repository) {
+		try {
+			Ref head = repository.getRef(HEAD);
+			return head != null && head.getObjectId() != null;
+		} catch (IOException e) {
+			return false;
+		}
+	}
+
+	private static String getCommandPath(String path) {
+		if ("".equals(path)) // Working directory //$NON-NLS-1$
+			return "."; //$NON-NLS-1$
+		else
+			return path;
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/RenameBranchOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/RenameBranchOperation.java
new file mode 100644
index 0000000..c1149f4
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/RenameBranchOperation.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Mathias Kinzler <mathias.kinzler@sap.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.CoreText;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.api.errors.JGitInternalException;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * This class implements renaming of a branch
+ */
+public class RenameBranchOperation implements IEGitOperation {
+	private final Repository repository;
+
+	private final Ref branch;
+
+	private final String newName;
+
+	/**
+	 * @param repository
+	 * @param branch
+	 *            the branch to rename
+	 * @param newName
+	 *            the new name
+	 */
+	public RenameBranchOperation(Repository repository, Ref branch,
+			String newName) {
+		this.repository = repository;
+		this.branch = branch;
+		this.newName = newName;
+	}
+
+	public void execute(IProgressMonitor m) throws CoreException {
+		IProgressMonitor monitor;
+		if (m == null)
+			monitor = new NullProgressMonitor();
+		else
+			monitor = m;
+
+		IWorkspaceRunnable action = new IWorkspaceRunnable() {
+			public void run(IProgressMonitor actMonitor) throws CoreException {
+				String taskName = NLS.bind(
+						CoreText.RenameBranchOperation_TaskName, branch
+								.getName(), newName);
+				actMonitor.beginTask(taskName, 1);
+				try {
+					new Git(repository).branchRename().setOldName(
+							branch.getName()).setNewName(newName).call();
+				} catch (JGitInternalException e) {
+					throw new CoreException(Activator.error(e.getMessage(), e));
+				} catch (GitAPIException e) {
+					throw new CoreException(Activator.error(e.getMessage(), e));
+				}
+				actMonitor.worked(1);
+				actMonitor.done();
+			}
+		};
+		// lock workspace to protect working tree changes
+		ResourcesPlugin.getWorkspace().run(action, monitor);
+	}
+
+	public ISchedulingRule getSchedulingRule() {
+		return ResourcesPlugin.getWorkspace().getRoot();
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/ResetOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/ResetOperation.java
new file mode 100644
index 0000000..48ea1ae
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/ResetOperation.java
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * Copyright (C) 2007, Dave Watson <dwatson@mimvista.com>
+ * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
+ * Copyright (C) 2010, Mathias Kinzler <mathias.kinzler@sap.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.egit.core.internal.CoreText;
+import org.eclipse.egit.core.internal.util.ProjectUtil;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.ResetCommand;
+import org.eclipse.jgit.api.ResetCommand.ResetType;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.team.core.TeamException;
+
+/**
+ * A class for changing a ref and possibly index and workdir too.
+ */
+public class ResetOperation implements IEGitOperation {
+
+	private final Repository repository;
+
+	private final String refName;
+
+	private final ResetType type;
+
+	/**
+	 * Construct a {@link ResetOperation}
+	 *
+	 * @param repository
+	 * @param refName
+	 * @param type
+	 */
+	public ResetOperation(Repository repository, String refName, ResetType type) {
+		this.repository = repository;
+		this.refName = refName;
+		this.type = type;
+	}
+
+	public ISchedulingRule getSchedulingRule() {
+		if (type == ResetType.HARD)
+			return ResourcesPlugin.getWorkspace().getRoot();
+		else
+			return null;
+	}
+
+	public void execute(IProgressMonitor m) throws CoreException {
+		IProgressMonitor monitor;
+		if (m == null)
+			monitor = new NullProgressMonitor();
+		else
+			monitor = m;
+		if (type == ResetType.HARD) {
+			IWorkspaceRunnable action = new IWorkspaceRunnable() {
+				public void run(IProgressMonitor actMonitor) throws CoreException {
+					reset(actMonitor);
+				}
+			};
+			// lock workspace to protect working tree changes
+			ResourcesPlugin.getWorkspace().run(action, monitor);
+		} else {
+			reset(monitor);
+		}
+	}
+
+	private void reset(IProgressMonitor monitor) throws CoreException {
+		monitor.beginTask(NLS.bind(CoreText.ResetOperation_performingReset,
+				type.toString().toLowerCase(), refName), 2);
+
+		IProject[] validProjects = null;
+		if (type == ResetType.HARD)
+			validProjects = ProjectUtil.getValidOpenProjects(repository);
+
+		ResetCommand reset = Git.wrap(repository).reset();
+		reset.setMode(type);
+		reset.setRef(refName);
+		try {
+			reset.call();
+		} catch (GitAPIException e) {
+			throw new TeamException(e.getLocalizedMessage(), e.getCause());
+		}
+		monitor.worked(1);
+
+		// only refresh if working tree changes
+		if (type == ResetType.HARD)
+			ProjectUtil.refreshValidProjects(validProjects,
+					new SubProgressMonitor(monitor, 1));
+
+		monitor.done();
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/RevertCommitOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/RevertCommitOperation.java
new file mode 100644
index 0000000..a3ef1f7
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/RevertCommitOperation.java
@@ -0,0 +1,116 @@
+/******************************************************************************
+ *  Copyright (c) 2011 GitHub Inc.
+ *  All rights reserved. This program and the accompanying materials
+ *  are made available under the terms of the Eclipse Public License v1.0
+ *  which accompanies this distribution, and is available at
+ *  http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *    Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *****************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import java.text.MessageFormat;
+import java.util.List;
+
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.egit.core.internal.CoreText;
+import org.eclipse.egit.core.internal.util.ProjectUtil;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.MergeResult;
+import org.eclipse.jgit.api.RevertCommand;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.team.core.TeamException;
+
+/**
+ * Operation to revert a commit
+ */
+public class RevertCommitOperation implements IEGitOperation {
+
+	private final Repository repo;
+
+	private final RevCommit commit;
+
+	private RevCommit newHead;
+
+	private List<Ref> reverted;
+
+	private MergeResult result;
+
+	/**
+	 * Create revert commit operation
+	 *
+	 * @param repository
+	 * @param commit
+	 */
+	public RevertCommitOperation(Repository repository, RevCommit commit) {
+		this.repo = repository;
+		this.commit = commit;
+	}
+
+	/**
+	 * @return new head commit
+	 */
+	public RevCommit getNewHead() {
+		return newHead;
+	}
+
+	/**
+	 * @return reverted refs
+	 */
+	public List<Ref> getRevertedRefs() {
+		return reverted;
+	}
+
+	public void execute(IProgressMonitor m) throws CoreException {
+		IProgressMonitor monitor = m != null ? m : new NullProgressMonitor();
+		IWorkspaceRunnable action = new IWorkspaceRunnable() {
+
+			public void run(IProgressMonitor pm) throws CoreException {
+				pm.beginTask("", 2); //$NON-NLS-1$
+
+				pm.subTask(MessageFormat.format(
+						CoreText.RevertCommitOperation_reverting, commit.name()));
+				RevertCommand command = new Git(repo).revert().include(commit);
+				try {
+					newHead = command.call();
+					reverted = command.getRevertedRefs();
+					result = command.getFailingResult();
+				} catch (GitAPIException e) {
+					throw new TeamException(e.getLocalizedMessage(),
+							e.getCause());
+				}
+				pm.worked(1);
+
+				ProjectUtil.refreshValidProjects(
+						ProjectUtil.getValidOpenProjects(repo),
+						new SubProgressMonitor(pm, 1));
+
+				pm.done();
+			}
+		};
+		ResourcesPlugin.getWorkspace().run(action, monitor);
+	}
+
+	public ISchedulingRule getSchedulingRule() {
+		return ResourcesPlugin.getWorkspace().getRoot();
+	}
+
+	/**
+	 * Get failing result of merge
+	 *
+	 * @return merge result
+	 */
+	public MergeResult getFailingResult() {
+		return result;
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/SetChangeIdTask.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/SetChangeIdTask.java
new file mode 100644
index 0000000..faf2490
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/SetChangeIdTask.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (C) 2011, Stefan Lay <stefan.lay@sap.com>
+ * Copyright (C) 2011, Matthias Sohn <matthias.sohn@sap.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import java.io.IOException;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.op.CloneOperation.PostCloneTask;
+import org.eclipse.jgit.lib.ConfigConstants;
+import org.eclipse.jgit.lib.Repository;
+
+/**
+ * Sets the config property gerrit.createchangeid
+ */
+public class SetChangeIdTask implements PostCloneTask {
+
+	private final boolean createchangeid;
+
+	/**
+	 * @param createchangeid
+	 */
+	public SetChangeIdTask(boolean createchangeid) {
+		this.createchangeid = createchangeid;
+	}
+
+	public void execute(Repository repository, IProgressMonitor monitor)
+			throws CoreException {
+		try {
+			repository.getConfig().setBoolean(ConfigConstants.CONFIG_GERRIT_SECTION,
+					null, ConfigConstants.CONFIG_KEY_CREATECHANGEID, createchangeid);
+			repository.getConfig().save();
+		} catch (IOException e) {
+			throw new CoreException(Activator.error(e.getMessage(), e));
+		}
+	}
+
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/SetRepositoryConfigPropertyTask.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/SetRepositoryConfigPropertyTask.java
new file mode 100644
index 0000000..a45d328
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/SetRepositoryConfigPropertyTask.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (C) 2012, Stefan Lay <stefan.lay@sap.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import java.io.IOException;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.op.CloneOperation.PostCloneTask;
+import org.eclipse.jgit.lib.Repository;
+
+/**
+ * Sets config properties for a repository
+ */
+public class SetRepositoryConfigPropertyTask implements PostCloneTask {
+
+	private final String section;
+	private final String subsection;
+	private final String name;
+	private final String value;
+
+	/**
+	 * @param section
+	 * @param subsection
+	 * @param name
+	 * @param value
+	 */
+	public SetRepositoryConfigPropertyTask(String section, String subsection, String name, String value) {
+		this.section = section;
+		this.subsection = subsection;
+		this.name = name;
+		this.value = value;
+	}
+
+	public void execute(Repository repository, IProgressMonitor monitor)
+			throws CoreException {
+		try {
+			repository.getConfig().setString(section, subsection, name, value);
+			repository.getConfig().save();
+		} catch (IOException e) {
+			throw new CoreException(Activator.error(e.getMessage(), e));
+		}
+	}
+
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/StashApplyOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/StashApplyOperation.java
new file mode 100644
index 0000000..ed9acbb
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/StashApplyOperation.java
@@ -0,0 +1,82 @@
+/******************************************************************************
+ *  Copyright (c) 2012 GitHub Inc.
+ *  All rights reserved. This program and the accompanying materials
+ *  are made available under the terms of the Eclipse Public License v1.0
+ *  which accompanies this distribution, and is available at
+ *  http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *    Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *****************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.egit.core.internal.util.ProjectUtil;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.api.errors.JGitInternalException;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.team.core.TeamException;
+
+/**
+ * Operation that applies a stashed commit in a repository
+ */
+public class StashApplyOperation implements IEGitOperation {
+
+	private final Repository repository;
+
+	private final RevCommit commit;
+
+	/**
+	 * Create operation for repository
+	 *
+	 * @param repository
+	 * @param commit
+	 */
+	public StashApplyOperation(final Repository repository,
+			final RevCommit commit) {
+		this.repository = repository;
+		this.commit = commit;
+	}
+
+	public void execute(IProgressMonitor monitor) throws CoreException {
+		IWorkspaceRunnable action = new IWorkspaceRunnable() {
+
+			public void run(IProgressMonitor pm) throws CoreException {
+				pm.beginTask("", 3); //$NON-NLS-1$
+				try {
+					IProject[] validProjects = ProjectUtil
+							.getValidOpenProjects(repository);
+					pm.worked(1);
+					Git.wrap(repository).stashApply()
+							.setStashRef(commit.name()).call();
+					pm.worked(1);
+					ProjectUtil.refreshValidProjects(validProjects,
+							new SubProgressMonitor(pm, 1));
+				} catch (JGitInternalException e) {
+					throw new TeamException(e.getLocalizedMessage(),
+							e.getCause());
+				} catch (GitAPIException e) {
+					throw new TeamException(e.getLocalizedMessage(),
+							e.getCause());
+				} finally {
+					pm.done();
+				}
+			}
+		};
+		ResourcesPlugin.getWorkspace().run(action,
+				monitor != null ? monitor : new NullProgressMonitor());
+	}
+
+	public ISchedulingRule getSchedulingRule() {
+		return ResourcesPlugin.getWorkspace().getRoot();
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/StashCreateOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/StashCreateOperation.java
new file mode 100644
index 0000000..5a701e1
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/StashCreateOperation.java
@@ -0,0 +1,98 @@
+/******************************************************************************
+ *  Copyright (c) 2012 GitHub Inc.
+ *  All rights reserved. This program and the accompanying materials
+ *  are made available under the terms of the Eclipse Public License v1.0
+ *  which accompanies this distribution, and is available at
+ *  http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *    Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *****************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.StashCreateCommand;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.api.errors.JGitInternalException;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.team.core.TeamException;
+
+/**
+ * Operation that creates a stashed commit for a repository
+ */
+public class StashCreateOperation implements IEGitOperation {
+
+	private final Repository repository;
+
+	private final String message;
+
+	private RevCommit commit;
+
+	/**
+	 * Create operation for repository
+	 *
+	 * @param repository
+	 */
+	public StashCreateOperation(final Repository repository) {
+		this(repository, null);
+	}
+
+	/**
+	 * Create operation for repository
+	 *
+	 * @param repository
+	 * @param message
+	 */
+	public StashCreateOperation(final Repository repository, final String message) {
+		this.repository = repository;
+		this.message = message;
+	}
+
+	/**
+	 * Get stashed commit
+	 *
+	 * @return commit
+	 */
+	public RevCommit getCommit() {
+		return commit;
+	}
+
+	public void execute(IProgressMonitor monitor) throws CoreException {
+		IWorkspaceRunnable action = new IWorkspaceRunnable() {
+
+			public void run(IProgressMonitor pm) throws CoreException {
+				try {
+					StashCreateCommand command = Git.wrap(repository).stashCreate();
+					if (message != null) {
+						command.setIndexMessage(message);
+						command.setWorkingDirectoryMessage(message);
+					}
+					commit = command.call();
+				} catch (JGitInternalException e) {
+					throw new TeamException(e.getLocalizedMessage(),
+							e.getCause());
+				} catch (GitAPIException e) {
+					throw new TeamException(e.getLocalizedMessage(),
+							e.getCause());
+				} finally {
+					if (commit != null)
+						repository.notifyIndexChanged();
+					pm.done();
+				}
+			}
+		};
+		ResourcesPlugin.getWorkspace().run(action,
+				monitor != null ? monitor : new NullProgressMonitor());
+	}
+
+	public ISchedulingRule getSchedulingRule() {
+		return ResourcesPlugin.getWorkspace().getRoot();
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/StashDropOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/StashDropOperation.java
new file mode 100644
index 0000000..4b8a180
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/StashDropOperation.java
@@ -0,0 +1,78 @@
+/******************************************************************************
+ *  Copyright (c) 2012 GitHub Inc.
+ *  All rights reserved. This program and the accompanying materials
+ *  are made available under the terms of the Eclipse Public License v1.0
+ *  which accompanies this distribution, and is available at
+ *  http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *    Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *****************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.StashDropCommand;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.api.errors.JGitInternalException;
+import org.eclipse.jgit.events.RefsChangedEvent;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.team.core.TeamException;
+
+/**
+ * Operation to drop a stashed commit
+ */
+public class StashDropOperation implements IEGitOperation {
+
+	private final int index;
+
+	private final Repository repo;
+
+	/**
+	 * Create an operation to drop the stashed commit with the given index
+	 *
+	 * @param repo
+	 * @param index
+	 */
+	public StashDropOperation(final Repository repo, final int index) {
+		if (index < 0)
+			throw new IllegalArgumentException();
+		this.index = index;
+		this.repo = repo;
+	}
+
+	public void execute(IProgressMonitor monitor) throws CoreException {
+		IWorkspaceRunnable action = new IWorkspaceRunnable() {
+
+			public void run(IProgressMonitor pm) throws CoreException {
+				pm.beginTask("", 1); //$NON-NLS-1$
+				StashDropCommand command = Git.wrap(repo).stashDrop();
+				command.setStashRef(index);
+				try {
+					command.call();
+					repo.fireEvent(new RefsChangedEvent());
+				} catch (JGitInternalException e) {
+					throw new TeamException(e.getLocalizedMessage(),
+							e.getCause());
+				} catch (GitAPIException e) {
+					throw new TeamException(e.getLocalizedMessage(),
+							e.getCause());
+				} finally {
+					pm.done();
+				}
+			}
+		};
+		ResourcesPlugin.getWorkspace().run(action,
+				monitor != null ? monitor : new NullProgressMonitor());
+	}
+
+	public ISchedulingRule getSchedulingRule() {
+		return ResourcesPlugin.getWorkspace().getRoot();
+	}
+
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/SubmoduleAddOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/SubmoduleAddOperation.java
new file mode 100644
index 0000000..e2589a3
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/SubmoduleAddOperation.java
@@ -0,0 +1,75 @@
+/******************************************************************************
+ *  Copyright (c) 2012 GitHub Inc.
+ *  All rights reserved. This program and the accompanying materials
+ *  are made available under the terms of the Eclipse Public License v1.0
+ *  which accompanies this distribution, and is available at
+ *  http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *    Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *****************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.egit.core.internal.EclipseGitProgressTransformer;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.SubmoduleAddCommand;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.team.core.TeamException;
+
+/**
+ * Operation to add a submodule to a repository
+ */
+public class SubmoduleAddOperation implements IEGitOperation {
+
+	private final Repository repo;
+
+	private final String path;
+
+	private final String uri;
+
+	/**
+	 * Create operation
+	 *
+	 * @param repo
+	 * @param path
+	 * @param uri
+	 */
+	public SubmoduleAddOperation(final Repository repo, final String path,
+			final String uri) {
+		this.repo = repo;
+		this.path = path;
+		this.uri = uri;
+	}
+
+	public void execute(IProgressMonitor monitor) throws CoreException {
+		IWorkspaceRunnable action = new IWorkspaceRunnable() {
+
+			public void run(IProgressMonitor pm) throws CoreException {
+				final SubmoduleAddCommand add = Git.wrap(repo).submoduleAdd();
+				add.setProgressMonitor(new EclipseGitProgressTransformer(pm));
+				add.setPath(path);
+				add.setURI(uri);
+				try {
+					if (add.call() != null)
+						repo.notifyIndexChanged();
+				} catch (GitAPIException e) {
+					throw new TeamException(e.getLocalizedMessage(),
+							e.getCause());
+				}
+			}
+		};
+		ResourcesPlugin.getWorkspace().run(action,
+				monitor != null ? monitor : new NullProgressMonitor());
+	}
+
+	public ISchedulingRule getSchedulingRule() {
+		return ResourcesPlugin.getWorkspace().getRoot();
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/SubmoduleSyncOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/SubmoduleSyncOperation.java
new file mode 100644
index 0000000..bc01178
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/SubmoduleSyncOperation.java
@@ -0,0 +1,88 @@
+/******************************************************************************
+ *  Copyright (c) 2012 GitHub Inc.
+ *  All rights reserved. This program and the accompanying materials
+ *  are made available under the terms of the Eclipse Public License v1.0
+ *  which accompanies this distribution, and is available at
+ *  http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *    Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *****************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.SubmoduleSyncCommand;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.team.core.TeamException;
+
+/**
+ * Operation that syncs a repository's submodule configurations
+ */
+public class SubmoduleSyncOperation implements IEGitOperation {
+
+	private final Repository repository;
+
+	private final Collection<String> paths;
+
+	/**
+	 * Create submodule sync operation
+	 *
+	 * @param repository
+	 */
+	public SubmoduleSyncOperation(final Repository repository) {
+		this.repository = repository;
+		paths = new ArrayList<String>();
+	}
+
+	/**
+	 * Add path of submodule to update
+	 *
+	 * @param path
+	 * @return this operation
+	 */
+	public SubmoduleSyncOperation addPath(final String path) {
+		paths.add(path);
+		return this;
+	}
+
+	public void execute(final IProgressMonitor monitor) throws CoreException {
+		IWorkspaceRunnable action = new IWorkspaceRunnable() {
+
+			public void run(IProgressMonitor pm) throws CoreException {
+				pm.beginTask("", 1); //$NON-NLS-1$
+				Map<String, String> updates = null;
+				try {
+					SubmoduleSyncCommand sync = Git.wrap(repository)
+							.submoduleSync();
+					for (String path : paths)
+						sync.addPath(path);
+					updates = sync.call();
+				} catch (GitAPIException e) {
+					throw new TeamException(e.getLocalizedMessage(),
+							e.getCause());
+				} finally {
+					if (updates != null && !updates.isEmpty())
+						repository.notifyIndexChanged();
+					pm.done();
+				}
+			}
+		};
+		ResourcesPlugin.getWorkspace().run(action,
+				monitor != null ? monitor : new NullProgressMonitor());
+	}
+
+	public ISchedulingRule getSchedulingRule() {
+		return null;
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/SubmoduleUpdateOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/SubmoduleUpdateOperation.java
new file mode 100644
index 0000000..c508408
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/SubmoduleUpdateOperation.java
@@ -0,0 +1,120 @@
+/******************************************************************************
+ *  Copyright (c) 2012 GitHub Inc.
+ *  All rights reserved. This program and the accompanying materials
+ *  are made available under the terms of the Eclipse Public License v1.0
+ *  which accompanies this distribution, and is available at
+ *  http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *    Kevin Sawicki (GitHub Inc.) - initial API and implementation
+ *****************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.egit.core.internal.EclipseGitProgressTransformer;
+import org.eclipse.egit.core.internal.util.ProjectUtil;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.SubmoduleInitCommand;
+import org.eclipse.jgit.api.SubmoduleUpdateCommand;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.submodule.SubmoduleWalk;
+import org.eclipse.team.core.TeamException;
+
+/**
+ * Operation that updates a repository's submodules
+ */
+public class SubmoduleUpdateOperation implements IEGitOperation {
+
+	private final Repository repository;
+
+	private final Collection<String> paths;
+
+	/**
+	 * Create submodule update operation
+	 *
+	 * @param repository
+	 */
+	public SubmoduleUpdateOperation(final Repository repository) {
+		this.repository = repository;
+		paths = new ArrayList<String>();
+	}
+
+	/**
+	 * Add path of submodule to update
+	 *
+	 * @param path
+	 * @return this operation
+	 */
+	public SubmoduleUpdateOperation addPath(final String path) {
+		paths.add(path);
+		return this;
+	}
+
+	public void execute(final IProgressMonitor monitor) throws CoreException {
+		IWorkspaceRunnable action = new IWorkspaceRunnable() {
+
+			public void run(IProgressMonitor pm) throws CoreException {
+				pm.beginTask("", 3); //$NON-NLS-1$
+				Git git = Git.wrap(repository);
+
+				Collection<String> updated = null;
+				try {
+					SubmoduleInitCommand init = git.submoduleInit();
+					for (String path : paths)
+						init.addPath(path);
+					init.call();
+					pm.worked(1);
+
+					SubmoduleUpdateCommand update = git.submoduleUpdate();
+					for (String path : paths)
+						update.addPath(path);
+					update.setProgressMonitor(new EclipseGitProgressTransformer(
+							new SubProgressMonitor(pm, 2)));
+					updated = update.call();
+					pm.worked(1);
+					SubProgressMonitor refreshMonitor = new SubProgressMonitor(
+							pm, 1);
+					refreshMonitor.beginTask("", updated.size()); //$NON-NLS-1$
+					for (String path : updated) {
+						Repository subRepo = SubmoduleWalk
+								.getSubmoduleRepository(repository, path);
+						if (subRepo != null)
+							ProjectUtil.refreshValidProjects(
+									ProjectUtil.getValidOpenProjects(subRepo),
+									new SubProgressMonitor(refreshMonitor, 1));
+						else
+							refreshMonitor.worked(1);
+					}
+					refreshMonitor.done();
+				} catch (GitAPIException e) {
+					throw new TeamException(e.getLocalizedMessage(),
+							e.getCause());
+				} catch (IOException e) {
+					throw new TeamException(e.getLocalizedMessage(),
+							e.getCause());
+				} finally {
+					if (updated != null && !updated.isEmpty())
+						repository.notifyIndexChanged();
+					pm.done();
+				}
+			}
+		};
+		ResourcesPlugin.getWorkspace().run(action,
+				monitor != null ? monitor : new NullProgressMonitor());
+	}
+
+	public ISchedulingRule getSchedulingRule() {
+		return ResourcesPlugin.getWorkspace().getRoot();
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/TagOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/TagOperation.java
new file mode 100644
index 0000000..80911d5
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/TagOperation.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import java.io.IOException;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.egit.core.internal.CoreText;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.ObjectInserter;
+import org.eclipse.jgit.lib.RefUpdate;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.lib.TagBuilder;
+import org.eclipse.jgit.lib.RefUpdate.Result;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.team.core.TeamException;
+
+/**
+ * Tags repository with given {@link TagBuilder} object.
+ */
+public class TagOperation implements IEGitOperation {
+
+	private final TagBuilder tag;
+	private final Repository repo;
+	private final boolean shouldMoveTag;
+
+	/**
+	 * Construct TagOperation
+	 *
+	 * @param repo
+	 * @param tag
+	 * @param shouldMoveTag if <code>true</code> it will replace tag with same name
+	 */
+	public TagOperation(Repository repo, TagBuilder tag, boolean shouldMoveTag) {
+		this.tag = tag;
+		this.repo = repo;
+		this.shouldMoveTag = shouldMoveTag;
+	}
+
+
+	public void execute(IProgressMonitor m) throws CoreException {
+		IProgressMonitor monitor;
+		if (m == null)
+			monitor = new NullProgressMonitor();
+		else
+			monitor = m;
+		try {
+			monitor.beginTask(NLS.bind(CoreText.TagOperation_performingTagging,
+					tag.getTag()), 3);
+
+			ObjectId tagId = updateTagObject();
+			monitor.worked(1);
+
+			updateRepo(tagId);
+			monitor.worked(1);
+
+		} finally {
+			monitor.done();
+		}
+	}
+
+	private void updateRepo(ObjectId tagId) throws TeamException {
+		String refName = Constants.R_TAGS + tag.getTag();
+
+		try {
+			RefUpdate tagRef = repo.updateRef(refName);
+			tagRef.setNewObjectId(tagId);
+
+			tagRef.setForceUpdate(shouldMoveTag);
+			Result updateResult = tagRef.update();
+
+			if (updateResult != Result.NEW && updateResult != Result.FORCED)
+				throw new TeamException(NLS.bind(CoreText.TagOperation_taggingFailure,
+						tag.getTag(), updateResult));
+		} catch (IOException e) {
+			throw new TeamException(NLS.bind(CoreText.TagOperation_taggingFailure,
+					tag.getTag(), e.getMessage()), e);
+		}
+	}
+
+	private ObjectId updateTagObject() throws TeamException {
+		ObjectId startPointRef = tag.getObjectId();
+
+		try {
+			ObjectId tagId;
+			repo.open(startPointRef);
+			ObjectInserter inserter = repo.newObjectInserter();
+			try {
+				tagId = inserter.insert(tag);
+				inserter.flush();
+			} finally {
+				inserter.release();
+			}
+			return tagId;
+		} catch (IOException e) {
+			throw new TeamException(NLS.bind(CoreText.TagOperation_objectIdNotFound,
+					tag.getTag(), e.getMessage()), e);
+		}
+	}
+
+
+	public ISchedulingRule getSchedulingRule() {
+		return null;
+	}
+
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/UntrackOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/UntrackOperation.java
new file mode 100644
index 0000000..1e5a897
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/op/UntrackOperation.java
@@ -0,0 +1,141 @@
+/*******************************************************************************
+ * Copyright (C) 2007, Robin Rosenberg <robin.rosenberg@dewire.com>
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
+ * Copyright (C) 2008, Google Inc.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.op;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.IdentityHashMap;
+import java.util.Map;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.CoreText;
+import org.eclipse.egit.core.internal.job.RuleUtil;
+import org.eclipse.egit.core.internal.project.GitProjectData;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.jgit.dircache.DirCacheEditor;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Remove one or more existing files/folders from the Git repository.
+ * <p>
+ * Accepts a collection of resources (files and/or directories) which should be
+ * removed from the their corresponding Git repositories. Resources in the
+ * collection can be associated with multiple repositories. The operation will
+ * automatically remove each resource from the correct Git repository.
+ * </p>
+ * <p>
+ * Resources are only scheduled for removal in the index-
+ * </p>
+ */
+public class UntrackOperation implements IEGitOperation {
+	private final Collection<? extends IResource> rsrcList;
+
+	private final IdentityHashMap<Repository, DirCacheEditor> edits;
+
+	private final IdentityHashMap<RepositoryMapping, Object> mappings;
+
+	/**
+	 * Create a new operation to stop tracking existing files/folders.
+	 *
+	 * @param rsrcs
+	 *            collection of {@link IResource}s which should be removed from
+	 *            the relevant Git repositories.
+	 */
+	public UntrackOperation(final Collection<? extends IResource> rsrcs) {
+		rsrcList = rsrcs;
+		edits = new IdentityHashMap<Repository, DirCacheEditor>();
+		mappings = new IdentityHashMap<RepositoryMapping, Object>();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.egit.core.op.IEGitOperation#execute(org.eclipse.core.runtime.IProgressMonitor)
+	 */
+	public void execute(IProgressMonitor m) throws CoreException {
+		IProgressMonitor monitor;
+		if (m == null)
+			monitor = new NullProgressMonitor();
+		else
+			monitor = m;
+
+		edits.clear();
+		mappings.clear();
+
+		monitor.beginTask(CoreText.UntrackOperation_adding, rsrcList.size() * 200);
+		try {
+			for (IResource obj : rsrcList) {
+				remove(obj);
+				monitor.worked(200);
+			}
+
+			for (Map.Entry<Repository, DirCacheEditor> e : edits.entrySet()) {
+				final Repository db = e.getKey();
+				final DirCacheEditor editor = e.getValue();
+				monitor.setTaskName(NLS.bind(CoreText.UntrackOperation_writingIndex, db.getDirectory()));
+				editor.commit();
+			}
+		} catch (RuntimeException e) {
+			throw new CoreException(Activator.error(CoreText.UntrackOperation_failed, e));
+		} catch (IOException e) {
+			throw new CoreException(Activator.error(CoreText.UntrackOperation_failed, e));
+		} finally {
+			for (final RepositoryMapping rm : mappings.keySet())
+				rm.fireRepositoryChanged();
+			for (DirCacheEditor editor:edits.values())
+				if (editor.getDirCache() != null)
+					editor.getDirCache().unlock();
+			edits.clear();
+			mappings.clear();
+			monitor.done();
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.egit.core.op.IEGitOperation#getSchedulingRule()
+	 */
+	public ISchedulingRule getSchedulingRule() {
+		return RuleUtil.getRuleForRepositories(rsrcList.toArray(new IResource[rsrcList.size()]));
+	}
+
+	private void remove(final IResource path) throws CoreException {
+		final IProject proj = path.getProject();
+		final GitProjectData pd = GitProjectData.get(proj);
+		if (pd == null)
+			return;
+		final RepositoryMapping rm = pd.getRepositoryMapping(path);
+		if (rm == null)
+			return;
+		final Repository db = rm.getRepository();
+
+		DirCacheEditor e = edits.get(db);
+		if (e == null) {
+			try {
+				e = db.lockDirCache().editor();
+			} catch (IOException err) {
+				throw new CoreException(Activator.error(CoreText.UntrackOperation_failed, err));
+			}
+			edits.put(db, e);
+			mappings.put(rm, rm);
+		}
+
+		if (path instanceof IContainer)
+			e.add(new DirCacheEditor.DeleteTree(rm.getRepoRelativePath(path)));
+		else
+			e.add(new DirCacheEditor.DeletePath(rm.getRepoRelativePath(path)));
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/project/GitProjectData.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/project/GitProjectData.java
new file mode 100644
index 0000000..a2e3b05
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/project/GitProjectData.java
@@ -0,0 +1,551 @@
+/*******************************************************************************
+ * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
+ * Copyright (C) 2008, Google Inc.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.project;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.QualifiedName;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.core.runtime.preferences.DefaultScope;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.CoreText;
+import org.eclipse.egit.core.internal.GitCorePreferences;
+import org.eclipse.egit.core.internal.GitProvider;
+import org.eclipse.egit.core.internal.JobFamilies;
+import org.eclipse.egit.core.internal.trace.GitTraceLocation;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.internal.storage.file.WindowCache;
+import org.eclipse.jgit.storage.file.WindowCacheConfig;
+import org.eclipse.jgit.util.FileUtils;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.team.core.RepositoryProvider;
+
+/**
+ * This class keeps information about how a project is mapped to
+ * a Git repository.
+ */
+public class GitProjectData {
+
+	private static final Map<IProject, GitProjectData> projectDataCache = new HashMap<IProject, GitProjectData>();
+
+	private static Set<RepositoryChangeListener> repositoryChangeListeners = new HashSet<RepositoryChangeListener>();
+
+	@SuppressWarnings("synthetic-access")
+	private static final IResourceChangeListener rcl = new RCL();
+
+	private static class RCL implements IResourceChangeListener {
+		@SuppressWarnings("synthetic-access")
+		public void resourceChanged(final IResourceChangeEvent event) {
+			switch (event.getType()) {
+			case IResourceChangeEvent.PRE_CLOSE:
+				uncache((IProject) event.getResource());
+				break;
+			case IResourceChangeEvent.PRE_DELETE:
+				try {
+					delete((IProject) event.getResource());
+				} catch (IOException e) {
+					Activator.logError(e.getMessage(), e);
+				}
+				break;
+			default:
+				break;
+			}
+		}
+	}
+
+	private static QualifiedName MAPPING_KEY = new QualifiedName(
+			GitProjectData.class.getName(), "RepositoryMapping");  //$NON-NLS-1$
+
+	/**
+	 * Start listening for resource changes.
+	 *
+	 * @param includeChange true to listen to content changes
+	 */
+	public static void attachToWorkspace(final boolean includeChange) {
+		trace("attachToWorkspace - addResourceChangeListener");  //$NON-NLS-1$
+		ResourcesPlugin.getWorkspace().addResourceChangeListener(
+				rcl,
+				(includeChange ? IResourceChangeEvent.POST_CHANGE : 0)
+						| IResourceChangeEvent.PRE_CLOSE
+						| IResourceChangeEvent.PRE_DELETE);
+	}
+
+	/**
+	 * Stop listening to resource changes
+	 */
+	public static void detachFromWorkspace() {
+		trace("detachFromWorkspace - removeResourceChangeListener"); //$NON-NLS-1$
+		ResourcesPlugin.getWorkspace().removeResourceChangeListener(rcl);
+	}
+
+	/**
+	 * Register a new listener for repository modification events.
+	 * <p>
+	 * This is a no-op if <code>objectThatCares</code> has already been
+	 * registered.
+	 * </p>
+	 *
+	 * @param objectThatCares
+	 *            the new listener to register. Must not be null.
+	 */
+	public static synchronized void addRepositoryChangeListener(
+			final RepositoryChangeListener objectThatCares) {
+		if (objectThatCares == null)
+			throw new NullPointerException();
+		repositoryChangeListeners.add(objectThatCares);
+	}
+
+	/**
+	 * Remove a registered {@link RepositoryChangeListener}
+	 *
+	 * @param objectThatCares
+	 *            The listener to remove
+	 */
+	public static synchronized void removeRepositoryChangeListener(
+			final RepositoryChangeListener objectThatCares) {
+		repositoryChangeListeners.remove(objectThatCares);
+	}
+
+	/**
+	 * Notify registered {@link RepositoryChangeListener}s of a change.
+	 *
+	 * @param which
+	 *            the repository which has had changes occur within it.
+	 */
+	static void fireRepositoryChanged(final RepositoryMapping which) {
+		Job job = new Job(CoreText.GitProjectData_repositoryChangedJobName) {
+
+			@Override
+			protected IStatus run(IProgressMonitor monitor) {
+				RepositoryChangeListener[] listeners = getRepositoryChangeListeners();
+				monitor.beginTask(
+						CoreText.GitProjectData_repositoryChangedTaskName,
+						listeners.length);
+
+				for (RepositoryChangeListener listener : listeners) {
+					listener.repositoryChanged(which);
+					monitor.worked(1);
+				}
+
+				monitor.done();
+
+				return Status.OK_STATUS;
+			}
+
+			@Override
+			public boolean belongsTo(Object family) {
+				if (JobFamilies.REPOSITORY_CHANGED.equals(family))
+					return true;
+
+				return super.belongsTo(family);
+			}
+		};
+
+		job.schedule();
+	}
+
+	/**
+	 * Get a copy of the current set of repository change listeners
+	 * <p>
+	 * The array has no references, so is safe for iteration and modification
+	 *
+	 * @return a copy of the current repository change listeners
+	 */
+	private static synchronized RepositoryChangeListener[] getRepositoryChangeListeners() {
+		return repositoryChangeListeners
+				.toArray(new RepositoryChangeListener[repositoryChangeListeners
+						.size()]);
+	}
+
+	/**
+	 * @param p
+	 * @return {@link GitProjectData} for the specified project
+	 */
+	public synchronized static GitProjectData get(final IProject p) {
+		try {
+			GitProjectData d = lookup(p);
+			if (d == null
+					&& RepositoryProvider.getProvider(p) instanceof GitProvider) {
+				d = new GitProjectData(p).load();
+				cache(p, d);
+			}
+			return d;
+		} catch (IOException err) {
+			Activator.logError(CoreText.GitProjectData_missing, err);
+			return null;
+		}
+	}
+
+	/**
+	 * Drop the Eclipse project from our association of projects/repositories
+	 *
+	 * @param p
+	 *            Eclipse project
+	 * @throws IOException
+	 *             if deletion of property files failed
+	 */
+	public static void delete(final IProject p) throws IOException {
+		trace("delete(" + p.getName() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
+		GitProjectData d = lookup(p);
+		if (d == null)
+			deletePropertyFiles(p);
+		else
+			d.deletePropertyFilesAndUncache();
+	}
+
+	/**
+	 * Add the Eclipse project to our association of projects/repositories
+	 *
+	 * @param p
+	 *            Eclipse project
+	 * @param d
+	 *            {@link GitProjectData} associated with this project
+	 */
+	public static void add(final IProject p, final GitProjectData d) {
+		trace("add(" + p.getName() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
+
+		cache(p, d);
+	}
+
+	static void trace(final String m) {
+		// TODO is this the right location?
+		if (GitTraceLocation.CORE.isActive())
+			GitTraceLocation.getTrace().trace(
+					GitTraceLocation.CORE.getLocation(),
+					"(GitProjectData) " + m); //$NON-NLS-1$
+	}
+
+	private synchronized static void cache(final IProject p,
+			final GitProjectData d) {
+		projectDataCache.put(p, d);
+	}
+
+	private synchronized static void uncache(final IProject p) {
+		if (projectDataCache.remove(p) != null) {
+			trace("uncacheDataFor(" //$NON-NLS-1$
+				+ p.getName() + ")"); //$NON-NLS-1$
+		}
+	}
+
+	private synchronized static GitProjectData lookup(final IProject p) {
+		return projectDataCache.get(p);
+	}
+
+	/**
+	 * Update the settings for the global window cache of the workspace.
+	 */
+	public static void reconfigureWindowCache() {
+		final WindowCacheConfig c = new WindowCacheConfig();
+		IEclipsePreferences d = DefaultScope.INSTANCE.getNode(Activator.getPluginId());
+		IEclipsePreferences p = InstanceScope.INSTANCE.getNode(Activator.getPluginId());
+		c.setPackedGitLimit(p.getInt(GitCorePreferences.core_packedGitLimit, d.getInt(GitCorePreferences.core_packedGitLimit, 0)));
+		c.setPackedGitWindowSize(p.getInt(GitCorePreferences.core_packedGitWindowSize, d.getInt(GitCorePreferences.core_packedGitWindowSize, 0)));
+		c.setPackedGitMMAP(p.getBoolean(GitCorePreferences.core_packedGitMMAP, d.getBoolean(GitCorePreferences.core_packedGitMMAP, false)));
+		c.setDeltaBaseCacheLimit(p.getInt(GitCorePreferences.core_deltaBaseCacheLimit, d.getInt(GitCorePreferences.core_deltaBaseCacheLimit, 0)));
+		c.setStreamFileThreshold(p.getInt(GitCorePreferences.core_streamFileThreshold, d.getInt(GitCorePreferences.core_streamFileThreshold, 0)));
+		WindowCache.reconfigure(c);
+	}
+
+	private final IProject project;
+
+	private final Collection<RepositoryMapping> mappings = new ArrayList<RepositoryMapping>();
+
+	private final Set<IResource> protectedResources = new HashSet<IResource>();
+
+	/**
+	 * Construct a {@link GitProjectData} for the mapping
+	 * of a project.
+	 *
+	 * @param p Eclipse project
+	 */
+	public GitProjectData(final IProject p) {
+		project = p;
+	}
+
+	/**
+	 * @return the Eclipse project mapped through this resource.
+	 */
+	public IProject getProject() {
+		return project;
+	}
+
+	/**
+	 * Set repository mappings
+	 *
+	 * @param newMappings
+	 */
+	public void setRepositoryMappings(final Collection<RepositoryMapping> newMappings) {
+		mappings.clear();
+		mappings.addAll(newMappings);
+		remapAll();
+	}
+
+	/**
+	 * Hide our private parts from the navigators other browsers.
+	 *
+	 * @throws CoreException
+	 */
+	public void markTeamPrivateResources() throws CoreException {
+		for (final Object rmObj : mappings) {
+			final RepositoryMapping rm = (RepositoryMapping)rmObj;
+			final IContainer c = rm.getContainer();
+			if (c == null)
+				continue; // Not fully mapped yet?
+
+			final IResource dotGit = c.findMember(Constants.DOT_GIT);
+			if (dotGit != null) {
+				try {
+					final Repository r = rm.getRepository();
+					final File dotGitDir = dotGit.getLocation().toFile()
+							.getCanonicalFile();
+					if (dotGitDir.equals(r.getDirectory())) {
+						trace("teamPrivate " + dotGit);  //$NON-NLS-1$
+						dotGit.setTeamPrivateMember(true);
+					}
+				} catch (IOException err) {
+					throw new CoreException(Activator.error(CoreText.Error_CanonicalFile, err));
+				}
+			}
+		}
+	}
+
+	/**
+	 * @param f
+	 * @return true if a resource is protected in this repository
+	 */
+	public boolean isProtected(final IResource f) {
+		return protectedResources.contains(f);
+	}
+
+	/**
+	 * @param resource any workbench resource contained within this project.
+	 * @return the mapping for the specified project
+	 */
+	public RepositoryMapping getRepositoryMapping(IResource resource) {
+		IResource r = resource;
+		try {
+			for (; r != null; r = r.getParent()) {
+				final RepositoryMapping m;
+
+				if (!r.isAccessible())
+					continue;
+				m = (RepositoryMapping) r.getSessionProperty(MAPPING_KEY);
+				if (m != null)
+					return m;
+			}
+		} catch (CoreException err) {
+			Activator.logError(
+					CoreText.GitProjectData_failedFindingRepoMapping, err);
+		}
+		return null;
+	}
+
+	private void deletePropertyFilesAndUncache() throws IOException {
+		deletePropertyFiles(getProject());
+		uncache(getProject());
+	}
+
+	private static void deletePropertyFiles(IProject project) throws IOException {
+		final File dir = propertyFile(project).getParentFile();
+		FileUtils.delete(dir, FileUtils.RECURSIVE);
+		trace("deleteDataFor(" //$NON-NLS-1$
+				+ project.getName() + ")"); //$NON-NLS-1$
+	}
+
+	/**
+	 * Store information about the repository connection in the workspace
+	 *
+	 * @throws CoreException
+	 */
+	public void store() throws CoreException {
+		final File dat = propertyFile();
+		final File tmp;
+		boolean ok = false;
+
+		try {
+			trace("save " + dat);  //$NON-NLS-1$
+			tmp = File.createTempFile(
+					"gpd_",  //$NON-NLS-1$
+					".prop",   //$NON-NLS-1$
+					dat.getParentFile());
+			final FileOutputStream o = new FileOutputStream(tmp);
+			try {
+				final Properties p = new Properties();
+				for (final RepositoryMapping repoMapping : mappings) {
+					repoMapping.store(p);
+				}
+				p.store(o, "GitProjectData");  //$NON-NLS-1$
+				ok = true;
+			} finally {
+				o.close();
+				if (!ok && tmp.exists()) {
+					FileUtils.delete(tmp);
+				}
+			}
+			if (dat.exists())
+				FileUtils.delete(dat);
+			if (!tmp.renameTo(dat)) {
+				if (tmp.exists())
+					FileUtils.delete(tmp);
+				throw new CoreException(
+						Activator.error(NLS.bind(
+								CoreText.GitProjectData_saveFailed, dat), null));
+			}
+		} catch (IOException ioe) {
+			throw new CoreException(Activator.error(
+					NLS.bind(CoreText.GitProjectData_saveFailed, dat), ioe));
+		}
+	}
+
+	private File propertyFile() {
+		return propertyFile(getProject());
+	}
+
+	private static File propertyFile(IProject project) {
+		return new File(project.getWorkingLocation(Activator.getPluginId())
+				.toFile(), "GitProjectData.properties"); //$NON-NLS-1$
+	}
+
+	private GitProjectData load() throws IOException {
+		final File dat = propertyFile();
+		trace("load " + dat);  //$NON-NLS-1$
+
+		final FileInputStream o = new FileInputStream(dat);
+		try {
+			final Properties p = new Properties();
+			p.load(o);
+
+			mappings.clear();
+			for (final Object keyObj : p.keySet()) {
+				final String key = keyObj.toString();
+				if (RepositoryMapping.isInitialKey(key)) {
+					mappings.add(new RepositoryMapping(p, key));
+				}
+			}
+		} finally {
+			o.close();
+		}
+
+		remapAll();
+		return this;
+	}
+
+	private void remapAll() {
+		protectedResources.clear();
+		for (final RepositoryMapping repoMapping : mappings) {
+			map(repoMapping);
+		}
+	}
+
+	private void map(final RepositoryMapping m) {
+		final IResource r;
+		final File git;
+		final IResource dotGit;
+		IContainer c = null;
+
+		m.clear();
+		r = getProject().findMember(m.getContainerPath());
+		if (r instanceof IContainer) {
+			c = (IContainer) r;
+		} else if (r != null) {
+			c = (IContainer) r.getAdapter(IContainer.class);
+		}
+
+		if (c == null) {
+			logGoneMappedResource(m);
+			m.clear();
+			return;
+		}
+		m.setContainer(c);
+
+		git = c.getLocation().append(m.getGitDirPath()).toFile();
+		if (!git.isDirectory() || !new File(git, "config").isFile()) { //$NON-NLS-1$
+			logGoneMappedResource(m);
+			m.clear();
+			return;
+		}
+
+		try {
+			m.setRepository(Activator.getDefault().getRepositoryCache()
+					.lookupRepository(git));
+		} catch (IOException ioe) {
+			logGoneMappedResource(m);
+			m.clear();
+			return;
+		}
+
+		m.fireRepositoryChanged();
+
+		trace("map "  //$NON-NLS-1$
+				+ c
+				+ " -> "  //$NON-NLS-1$
+				+ m.getRepository());
+		try {
+			c.setSessionProperty(MAPPING_KEY, m);
+		} catch (CoreException err) {
+			Activator.logError(
+					CoreText.GitProjectData_failedToCacheRepoMapping, err);
+		}
+
+		dotGit = c.findMember(Constants.DOT_GIT);
+		if (dotGit != null && dotGit.getLocation().toFile().equals(git)) {
+			protect(dotGit);
+		}
+	}
+
+	private void logGoneMappedResource(final RepositoryMapping m) {
+		Activator.logError(MessageFormat.format(
+				CoreText.GitProjectData_mappedResourceGone, m.toString()),
+				new FileNotFoundException(m.getContainerPath().toString()));
+	}
+
+	private void protect(IResource resource) {
+		IResource c = resource;
+		while (c != null && !c.equals(getProject())) {
+			trace("protect " + c);  //$NON-NLS-1$
+			protectedResources.add(c);
+			try {
+				c.setTeamPrivateMember(true);
+			} catch (CoreException e) {
+				Activator.logError(MessageFormat.format(
+						CoreText.GitProjectData_FailedToMarkTeamPrivate,
+						c.getFullPath()),
+						e);
+			}
+			c = c.getParent();
+		}
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/project/RepositoryChangeListener.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/project/RepositoryChangeListener.java
new file mode 100644
index 0000000..a1299d8
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/project/RepositoryChangeListener.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (C) 2007, Shawn O. Pearce <spearce@spearce.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.project;
+
+/**
+ * Receives notification of a repository change event.
+ * <p>
+ * A change listener may be called from any thread, especially background job
+ * threads, but also from the UI thread. Implementors are encouraged to complete
+ * quickly, and make arrange for their tasks to run on the UI event thread if
+ * necessary.
+ * </p>
+ */
+public interface RepositoryChangeListener {
+	/**
+	 * Invoked when a repository has had some or all of its contents change.
+	 *
+	 * @param which
+	 *            the affected repository. Never null.
+	 */
+	public void repositoryChanged(RepositoryMapping which);
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/project/RepositoryFinder.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/project/RepositoryFinder.java
new file mode 100644
index 0000000..a1d80ee
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/project/RepositoryFinder.java
@@ -0,0 +1,187 @@
+/*******************************************************************************
+ * Copyright (C) 2007, Robin Rosenberg <robin.rosenberg@dewire.com>
+ * Copyright (C) 2007, Shawn O. Pearce <spearce@spearce.org>
+ * Copyright (C) 2008, Google Inc.
+ * Copyright (C) 2012, François Rey <eclipse.org_@_francois_._rey_._name>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.project;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.egit.core.internal.CoreText;
+import org.eclipse.egit.core.internal.trace.GitTraceLocation;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.util.SystemReader;
+
+/**
+ * Searches for existing Git repositories associated with a project's files.
+ * <p>
+ * This finder algorithm searches a project's contained files to see if any of
+ * them are located within the working directory of an existing Git repository.
+ * By default linked resources are ignored and not included in the search.
+ * </p>
+ * <p>
+ * The search algorithm is exhaustive, it will find all matching repositories.
+ * For the project itself and possibly for each linked container within the
+ * project it scans down the local filesystem trees to locate any Git
+ * repositories which may be found there. It also scans up the local filesystem
+ * tree to locate any Git repository which may be outside of Eclipse's
+ * workspace-view of the world.
+ * In short, if there is a Git repository associated, it finds it.
+ * </p>
+ */
+public class RepositoryFinder {
+	private final IProject proj;
+
+	private final Collection<RepositoryMapping> results = new ArrayList<RepositoryMapping>();
+	private final Set<File> gitdirs = new HashSet<File>();
+
+	private Set<String> ceilingDirectories = new HashSet<String>();
+
+	/**
+	 * Create a new finder to locate Git repositories for a project.
+	 *
+	 * @param p
+	 *            the project this new finder should locate the existing Git
+	 *            repositories of.
+	 */
+	public RepositoryFinder(final IProject p) {
+		proj = p;
+		String ceilingDirectoriesVar = SystemReader.getInstance().getenv(
+				Constants.GIT_CEILING_DIRECTORIES_KEY);
+		if (ceilingDirectoriesVar != null) {
+			ceilingDirectories.addAll(Arrays.asList(ceilingDirectoriesVar
+					.split(File.pathSeparator)));
+		}
+	}
+
+	/**
+	 * Run the search algorithm, ignoring linked resources.
+	 *
+	 * @param m
+	 *            a progress monitor to report feedback to; may be null.
+	 * @return all found {@link RepositoryMapping} instances associated with the
+	 *         project supplied to this instance's constructor.
+	 * @throws CoreException
+	 *             Eclipse was unable to access its workspace, and threw up on
+	 *             us. We're throwing it back at the caller.
+	 */
+	public Collection<RepositoryMapping> find(IProgressMonitor m)
+			throws CoreException {
+		return find(m, false);
+	}
+
+	/**
+	 * Run the search algorithm.
+	 *
+	 * @param m
+	 *            a progress monitor to report feedback to; may be null.
+	 * @param searchLinkedFolders
+	 *            specify if linked folders should be included in the search
+	 * @return all found {@link RepositoryMapping} instances associated with the
+	 *         project supplied to this instance's constructor.
+	 * @throws CoreException
+	 *             Eclipse was unable to access its workspace, and threw up on
+	 *             us. We're throwing it back at the caller.
+	 * @since 2.3
+	 */
+	public Collection<RepositoryMapping> find(IProgressMonitor m, boolean searchLinkedFolders)
+			throws CoreException {
+		IProgressMonitor monitor;
+		if (m == null)
+			monitor = new NullProgressMonitor();
+		else
+			monitor = m;
+		find(monitor, proj, searchLinkedFolders);
+		return results;
+	}
+
+	private void find(final IProgressMonitor m, final IContainer c, boolean searchLinkedFolders)
+				throws CoreException {
+		if (!searchLinkedFolders && c.isLinked())
+			return; // Ignore linked folders
+		final IPath loc = c.getLocation();
+
+		m.beginTask("", 101);  //$NON-NLS-1$
+		m.subTask(CoreText.RepositoryFinder_finding);
+		try {
+			if (loc != null) {
+				final File fsLoc = loc.toFile();
+				assert fsLoc.isAbsolute();
+				final File ownCfg = configFor(fsLoc);
+				final IResource[] children;
+
+				if (ownCfg.isFile()) {
+					register(c, ownCfg.getParentFile());
+				}
+				if (c instanceof IProject) {
+					File p = fsLoc.getParentFile();
+					while (p != null) {
+						// TODO is this the right location?
+						if (GitTraceLocation.CORE.isActive())
+							GitTraceLocation.getTrace().trace(
+									GitTraceLocation.CORE.getLocation(),
+									"Looking at candidate dir: " //$NON-NLS-1$
+											+ p);
+						final File pCfg = configFor(p);
+						if (pCfg.isFile()) {
+							register(c, pCfg.getParentFile());
+						}
+						if (ceilingDirectories.contains(p.getPath()))
+							break;
+						p = p.getParentFile();
+					}
+				}
+				m.worked(1);
+
+				children = c.members();
+				if (children != null && children.length > 0) {
+					final int scale = 100 / children.length;
+					for (int k = 0; k < children.length; k++) {
+						final IResource o = children[k];
+						if (o instanceof IContainer
+								&& !o.getName().equals(Constants.DOT_GIT)) {
+							find(new SubProgressMonitor(m, scale),
+									(IContainer) o, searchLinkedFolders);
+						} else {
+							m.worked(scale);
+						}
+					}
+				}
+			}
+		} finally {
+			m.done();
+		}
+	}
+
+	private File configFor(final File fsLoc) {
+		return new File(new File(fsLoc, Constants.DOT_GIT),
+				"config");  //$NON-NLS-1$
+	}
+
+	private void register(final IContainer c, final File gitdir) {
+		File f = gitdir.getAbsoluteFile();
+		if (gitdirs.contains(f))
+			return;
+		gitdirs.add(f);
+		results.add(new RepositoryMapping(c, f));
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/project/RepositoryMapping.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/project/RepositoryMapping.java
new file mode 100644
index 0000000..e80dd97
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/project/RepositoryMapping.java
@@ -0,0 +1,338 @@
+/*******************************************************************************
+ * Copyright (C) 2007, Dave Watson <dwatson@mimvista.com>
+ * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
+ * Copyright (C) 2008, Shunichi Fuji <palglowr@gmail.com>
+ * Copyright (C) 2008, Google Inc.
+ * Copyright (C) 2012, 2013 Robin Stocker <robin@nibor.org>
+ * Copyright (C) 2013, François Rey <eclipse.org_@_francois_._rey_._name>
+ * Copyright (C) 2013, Gunnar Wagenknecht <gunnar@wagenknecht.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.project;
+
+import static org.eclipse.egit.core.internal.util.ResourceUtil.isNonWorkspace;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Properties;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.egit.core.internal.GitProvider;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.team.core.RepositoryProvider;
+
+/**
+ * This class provides means to map resources, projects and repositories
+ */
+public class RepositoryMapping {
+	static boolean isInitialKey(final String key) {
+		return key.endsWith(".gitdir");  //$NON-NLS-1$
+	}
+
+	private final String containerPathString;
+
+	private IPath containerPath;
+
+	private final String gitDirPathString;
+
+	private IPath gitDirPath;
+
+	private IPath gitDirAbsolutePath;
+
+	private Repository db;
+
+	private String workdirPrefix;
+
+	private IContainer container;
+
+	/**
+	 * Construct a {@link RepositoryMapping} for a previously connected project.
+	 *
+	 * @param p TODO
+	 * @param initialKey TODO
+	 */
+	public RepositoryMapping(final Properties p, final String initialKey) {
+		final int dot = initialKey.lastIndexOf('.');
+
+		containerPathString = initialKey.substring(0, dot);
+		gitDirPathString = p.getProperty(initialKey);
+	}
+
+	/**
+	 * Construct a {@link RepositoryMapping} for previously
+	 * unknown project.
+	 *
+	 * @param mappedContainer
+	 * @param gitDir
+	 */
+	public RepositoryMapping(final IContainer mappedContainer, final File gitDir) {
+		final IPath cLoc = mappedContainer.getLocation()
+				.removeTrailingSeparator();
+		final IPath gLoc = Path.fromOSString(gitDir.getAbsolutePath())
+				.removeTrailingSeparator();
+		final IPath gLocParent = gLoc.removeLastSegments(1);
+
+		container = mappedContainer;
+		containerPathString = container.getProjectRelativePath()
+				.toPortableString();
+
+		if (cLoc.isPrefixOf(gLoc)) {
+			int matchingSegments = gLoc.matchingFirstSegments(cLoc);
+			IPath remainder = gLoc.removeFirstSegments(matchingSegments);
+			String device = remainder.getDevice();
+			if (device == null)
+				gitDirPathString = remainder.toPortableString();
+			else
+				gitDirPathString = remainder.toPortableString().substring(
+						device.length());
+		} else if (gLocParent.isPrefixOf(cLoc)) {
+			int cnt = cLoc.segmentCount() - cLoc.matchingFirstSegments(gLocParent);
+			StringBuilder p = new StringBuilder("");  //$NON-NLS-1$
+			while (cnt-- > 0) {
+				p.append("../");  //$NON-NLS-1$
+			}
+			p.append(gLoc.segment(gLoc.segmentCount() - 1));
+			gitDirPathString = p.toString();
+		} else {
+			gitDirPathString = gLoc.toPortableString();
+		}
+	}
+
+	/**
+	 * @return the container path corresponding to git repository
+	 */
+	public IPath getContainerPath() {
+		if (containerPath == null)
+			containerPath = Path.fromPortableString(containerPathString);
+		return containerPath;
+	}
+
+	IPath getGitDirPath() {
+		if (gitDirPath == null)
+			gitDirPath = Path.fromPortableString(gitDirPathString);
+		return gitDirPath;
+	}
+
+	/**
+	 * @return the workdir file, i.e. where the files are checked out
+	 */
+	public File getWorkTree() {
+		return getRepository().getWorkTree();
+	}
+
+	synchronized void clear() {
+		db = null;
+		workdirPrefix = null;
+		container = null;
+	}
+
+	/**
+	 * @return a reference to the repository object handled by this mapping
+	 */
+	public synchronized Repository getRepository() {
+		return db;
+	}
+
+	synchronized void setRepository(final Repository r) {
+		db = r;
+
+		try {
+			workdirPrefix = getWorkTree().getCanonicalPath();
+		} catch (IOException err) {
+			workdirPrefix = getWorkTree().getAbsolutePath();
+		}
+		workdirPrefix = workdirPrefix.replace('\\', '/');
+		if (!workdirPrefix.endsWith("/"))  //$NON-NLS-1$
+			workdirPrefix += "/";  //$NON-NLS-1$
+	}
+
+	/**
+	 * @return the mapped container (currently project)
+	 */
+	public synchronized IContainer getContainer() {
+		return container;
+	}
+
+	synchronized void setContainer(final IContainer c) {
+		container = c;
+	}
+
+	/**
+	 * Notify registered {@link RepositoryChangeListener}s of a change.
+	 *
+	 * @see GitProjectData#addRepositoryChangeListener(RepositoryChangeListener)
+	 */
+	public void fireRepositoryChanged() {
+		GitProjectData.fireRepositoryChanged(this);
+	}
+
+	synchronized void store(final Properties p) {
+		p.setProperty(containerPathString + ".gitdir", gitDirPathString); //$NON-NLS-1$
+	}
+
+	public String toString() {
+		IPath absolutePath = getGitDirAbsolutePath();
+		return "RepositoryMapping[" //$NON-NLS-1$
+				+ format(containerPathString)
+				+ " -> '" //$NON-NLS-1$
+				+ format(gitDirPathString)
+				+ "', absolute path: '"  //$NON-NLS-1$
+				+ format(absolutePath) + "' ]"; //$NON-NLS-1$
+	}
+
+	private String format(Object o) {
+		if (o == null)
+			return "<null>"; //$NON-NLS-1$
+		else if (o.toString().length() == 0)
+			return "<empty>"; //$NON-NLS-1$
+		else
+			return o.toString();
+	}
+
+	/**
+	 * This method should only be called for resources that are actually in this
+	 * repository, so we can safely assume that their path prefix matches
+	 * {@link #getWorkTree()}. Testing that here is rather expensive so we don't
+	 * bother.
+	 *
+	 * @param rsrc
+	 * @return the path relative to the Git repository, including base name. An
+	 *         empty string (<code>""</code>) if passed resource corresponds to
+	 *         working directory (root). <code>null</code> if the path cannot be
+	 *         determined.
+	 */
+	public String getRepoRelativePath(final IResource rsrc) {
+		IPath location = rsrc.getLocation();
+		if (location == null)
+			return null;
+		return getRepoRelativePath(location);
+	}
+
+	/**
+	 * This method should only be called for resources that are actually in this
+	 * repository, so we can safely assume that their path prefix matches
+	 * {@link #getWorkTree()}. Testing that here is rather expensive so we don't
+	 * bother.
+	 *
+	 * @param location
+	 * @return the path relative to the Git repository, including base name. An
+	 *         empty string (<code>""</code>) if passed location corresponds to
+	 *         working directory (root). <code>null</code> if the path cannot be
+	 *         determined.
+	 */
+	public String getRepoRelativePath(IPath location) {
+		final int pfxLen = workdirPrefix.length();
+		final String p = location.toString();
+		final int pLen = p.length();
+		if (pLen > pfxLen)
+			return p.substring(pfxLen);
+		if (pLen == pfxLen - 1)
+			return ""; //$NON-NLS-1$
+		return null;
+	}
+
+	/**
+	 * Get the repository mapping for a resource. If the given resource is a
+	 * linked resource, the raw location of the resource will be used to
+	 * determine a repository mapping.
+	 *
+	 * @param resource
+	 * @return the RepositoryMapping for this resource, or null for non
+	 *         GitProvider.
+	 */
+	public static RepositoryMapping getMapping(final IResource resource) {
+		if (isNonWorkspace(resource))
+			return null;
+
+		if (resource.isLinked(IResource.CHECK_ANCESTORS))
+			return getMapping(resource.getLocation());
+
+		IProject project = resource.getProject();
+		if (project == null)
+			return null;
+
+		final RepositoryProvider rp = RepositoryProvider.getProvider(project);
+		if (!(rp instanceof GitProvider))
+			return null;
+
+		if (((GitProvider)rp).getData() == null)
+			return null;
+
+		return ((GitProvider)rp).getData().getRepositoryMapping(resource);
+	}
+
+	/**
+	 * Get the repository mapping for a path if it exists.
+	 *
+	 * @param path
+	 * @return the RepositoryMapping for this path,
+	 *         or null for non GitProvider.
+	 */
+	public static RepositoryMapping getMapping(IPath path) {
+		IProject[] projects = ResourcesPlugin.getWorkspace().getRoot()
+				.getProjects();
+
+		for (IProject project : projects) {
+			if (isNonWorkspace(project))
+				continue;
+			RepositoryMapping mapping = getMapping(project);
+			if (mapping == null)
+				continue;
+
+			IPath workingTree = new Path(mapping.getWorkTree().toString());
+			if (workingTree.isPrefixOf(path))
+				return mapping;
+		}
+
+		return null;
+	}
+
+	/**
+	 * Finds a RepositoryMapping related to a given repository
+	 *
+	 * @param repository
+	 * @return a RepositoryMapping related to repository. Null if no
+	 *         RepositoryMapping exists.
+	 */
+	public static RepositoryMapping findRepositoryMapping(Repository repository) {
+		final IProject[] projects = ResourcesPlugin.getWorkspace().getRoot()
+				.getProjects();
+		for (IProject project : projects) {
+			RepositoryMapping mapping = RepositoryMapping.getMapping(project);
+			if (mapping != null && mapping.getRepository() == repository)
+				return mapping;
+		}
+		return null;
+	}
+
+	/**
+	 * @return the name of the .git directory
+	 */
+	public String getGitDir() {
+		return gitDirPathString;
+	}
+
+	/**
+	 * @return The GIT DIR absolute path
+	 */
+	public synchronized IPath getGitDirAbsolutePath() {
+		if (gitDirAbsolutePath == null) {
+			if (container != null) {
+				IPath cloc = container.getLocation();
+				if (cloc != null)
+					gitDirAbsolutePath = cloc.append(getGitDirPath());
+			}
+		}
+		return gitDirAbsolutePath;
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/securestorage/EGitSecureStore.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/securestorage/EGitSecureStore.java
new file mode 100644
index 0000000..820a597
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/securestorage/EGitSecureStore.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Jens Baumgart <jens.baumgart@sap.com>
+ * Copyright (C) 2010, Edwin Kempin <edwin.kempin@sap.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.securestorage;
+
+import java.io.IOException;
+
+import org.eclipse.equinox.security.storage.EncodingUtils;
+import org.eclipse.equinox.security.storage.ISecurePreferences;
+import org.eclipse.equinox.security.storage.StorageException;
+import org.eclipse.jgit.transport.URIish;
+
+/**
+ * This class wraps the Eclipse secure store. It provides methods to put
+ * credentials for a given URI to the secure store and to retrieve credentials
+ * for a given URI.
+ */
+public class EGitSecureStore {
+
+	private static final String USER = "user"; //$NON-NLS-1$
+
+	private static final String PASSWORD = "password"; //$NON-NLS-1$
+
+	private static final String GIT_PATH_PREFIX = "/GIT/"; //$NON-NLS-1$
+
+	private final ISecurePreferences preferences;
+
+	/**
+	 * Constructor
+	 *
+	 * @param preferences
+	 *            the Eclipse secure store should be passed here if not in test
+	 *            mode
+	 */
+	public EGitSecureStore(ISecurePreferences preferences) {
+		this.preferences = preferences;
+	}
+
+	/**
+	 * Puts credentials for the given URI into the secure store
+	 *
+	 * @param uri
+	 * @param credentials
+	 * @throws StorageException
+	 * @throws IOException
+	 */
+	public void putCredentials(URIish uri, UserPasswordCredentials credentials)
+			throws StorageException, IOException {
+		String pathName = calcNodePath(uri);
+		ISecurePreferences node = preferences.node(pathName);
+		node.put(USER, credentials.getUser(), false);
+		node.put(PASSWORD, credentials.getPassword(), true);
+		node.flush();
+	}
+
+	/**
+	 * Retrieves credentials stored for the given URI from the secure store
+	 *
+	 * @param uri
+	 * @return credentials
+	 * @throws StorageException
+	 */
+	public UserPasswordCredentials getCredentials(URIish uri)
+			throws StorageException {
+		String pathName = calcNodePath(uri);
+		if (!preferences.nodeExists(pathName))
+			return null;
+		ISecurePreferences node = preferences.node(pathName);
+		String user = node.get(USER, ""); //$NON-NLS-1$
+		String password = node.get(PASSWORD, ""); //$NON-NLS-1$
+		if (uri.getUser() != null && !user.equals(uri.getUser()))
+			return null;
+		return new UserPasswordCredentials(user, password);
+	}
+
+	static String calcNodePath(URIish uri) {
+		URIish storedURI = uri.setUser(null).setPass(null).setPath(null);
+		if (uri.getPort() == -1) {
+			String s = uri.getScheme();
+			if ("http".equals(s)) //$NON-NLS-1$
+				storedURI = storedURI.setPort(80);
+			else if ("https".equals(s)) //$NON-NLS-1$
+				storedURI = storedURI.setPort(443);
+			else if ("ssh".equals(s) || "sftp".equals(s)) //$NON-NLS-1$ //$NON-NLS-2$
+				storedURI = storedURI.setPort(22);
+			else if ("ftp".equals(s)) //$NON-NLS-1$
+				storedURI = storedURI.setPort(21);
+		}
+		String pathName = GIT_PATH_PREFIX
+				+ EncodingUtils.encodeSlashes(storedURI.toString());
+		return pathName;
+	}
+
+	/**
+	 * Clear credentials for the given uri.
+	 *
+	 * @param uri
+	 * @throws IOException
+	 */
+	public void clearCredentials(URIish uri) throws IOException {
+		String pathName = calcNodePath(uri);
+		if (!preferences.nodeExists(pathName))
+			return;
+		ISecurePreferences node = preferences.node(pathName);
+		node.removeNode();
+		node.flush();
+	}
+
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/securestorage/UserPasswordCredentials.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/securestorage/UserPasswordCredentials.java
new file mode 100644
index 0000000..eed09ff
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/securestorage/UserPasswordCredentials.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Jens Baumgart <jens.baumgart@sap.com>
+ * Copyright (C) 2010, Edwin Kempin <edwin.kempin@sap.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.securestorage;
+
+/**
+ * Implements a credentials object containing user and password.
+ */
+public class UserPasswordCredentials {
+
+	private final String user;
+	private final String password;
+
+	/**
+	 * @param user
+	 * @param password
+	 */
+	public UserPasswordCredentials(String user, String password) {
+		this.user = user;
+		this.password = password;
+	}
+
+	/**
+	 * @return user
+	 */
+	public String getUser() {
+		return user;
+	}
+
+	/**
+	 * @return password
+	 */
+	public String getPassword() {
+		return password;
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/storage/BlobStorage.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/storage/BlobStorage.java
index 9988cd1..fc49e47 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/storage/BlobStorage.java
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/storage/BlobStorage.java
@@ -18,9 +18,9 @@
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.CoreText;
-import org.eclipse.egit.core.RepositoryUtil;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.CoreText;
+import org.eclipse.egit.core.internal.RepositoryUtil;
 import org.eclipse.jgit.errors.IncorrectObjectTypeException;
 import org.eclipse.jgit.errors.MissingObjectException;
 import org.eclipse.jgit.lib.Constants;
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/storage/CommitFileRevision.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/storage/CommitFileRevision.java
index dc71878..b86eda2 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/storage/CommitFileRevision.java
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/storage/CommitFileRevision.java
@@ -17,9 +17,9 @@
 import org.eclipse.core.resources.IStorage;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.CoreText;
-import org.eclipse.egit.core.GitTag;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.CoreText;
+import org.eclipse.egit.core.internal.GitTag;
 import org.eclipse.jgit.lib.AnyObjectId;
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.PersonIdent;
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/storage/GitFileHistory.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/storage/GitFileHistory.java
index 84af96f..978e962 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/storage/GitFileHistory.java
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/storage/GitFileHistory.java
@@ -15,9 +15,9 @@
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.runtime.IAdaptable;
 import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.CoreText;
-import org.eclipse.egit.core.project.RepositoryMapping;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.CoreText;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
 import org.eclipse.osgi.util.NLS;
 import org.eclipse.team.core.history.IFileHistoryProvider;
 import org.eclipse.team.core.history.IFileRevision;
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/storage/IndexFileRevision.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/storage/IndexFileRevision.java
index bf1fbbd..9ce26c5 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/storage/IndexFileRevision.java
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/storage/IndexFileRevision.java
@@ -17,8 +17,8 @@
 import org.eclipse.core.resources.IStorage;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.CoreText;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.CoreText;
 import org.eclipse.jgit.dircache.DirCache;
 import org.eclipse.jgit.dircache.DirCacheEntry;
 import org.eclipse.jgit.lib.ObjectId;
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/storage/WorkingTreeFileRevision.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/storage/WorkingTreeFileRevision.java
index fce50d1..e6c45c9 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/storage/WorkingTreeFileRevision.java
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/storage/WorkingTreeFileRevision.java
@@ -18,7 +18,7 @@
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.core.Activator;
+import org.eclipse.egit.core.internal.Activator;
 import org.eclipse.team.core.history.IFileRevision;
 
 /** An {@link IFileRevision} for the current version in the working tree */
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitBaseResourceVariantTree.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitBaseResourceVariantTree.java
new file mode 100644
index 0000000..8665486
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitBaseResourceVariantTree.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2010 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Dariusz Luksza <dariusz@luksza.org>
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.synchronize;
+
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeData;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeDataSet;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.team.core.variants.SessionResourceVariantByteStore;
+
+class GitBaseResourceVariantTree extends GitResourceVariantTree {
+
+	public GitBaseResourceVariantTree(GitSyncCache cache, GitSynchronizeDataSet gsds) {
+		super(new SessionResourceVariantByteStore(), cache, gsds);
+	}
+
+	@Override
+	protected ObjectId getObjectId(ThreeWayDiffEntry diffEntry) {
+		return diffEntry.getBaseId().toObjectId();
+	}
+
+	@Override
+	protected RevCommit getCommitId(GitSynchronizeData gsd) {
+		return gsd.getDstRevCommit();
+	}
+
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitCommitsModelCache.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitCommitsModelCache.java
new file mode 100644
index 0000000..91aeb04
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitCommitsModelCache.java
@@ -0,0 +1,456 @@
+/*******************************************************************************
+ * Copyright (C) 2011, 2012 Dariusz Luksza <dariusz@luksza.org> and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.synchronize;
+
+import static org.eclipse.jgit.lib.ObjectId.zeroId;
+import static org.eclipse.jgit.treewalk.filter.TreeFilter.ANY_DIFF;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.jgit.lib.AbbreviatedObjectId;
+import org.eclipse.jgit.lib.MutableObjectId;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevFlag;
+import org.eclipse.jgit.revwalk.RevFlagSet;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.treewalk.EmptyTreeIterator;
+import org.eclipse.jgit.treewalk.TreeWalk;
+import org.eclipse.jgit.treewalk.filter.AndTreeFilter;
+import org.eclipse.jgit.treewalk.filter.TreeFilter;
+
+/**
+ * Retrieves list of commits and the changes associated with each commit
+ */
+public class GitCommitsModelCache {
+
+	/**
+	 * Constant copied from org.eclipse.compare.structuremergeviewer.Differencer.ADDITION
+	 * in order to avoid UI dependencies introduced by the org.eclipse.compare bundle
+	 */
+	public static final int ADDITION = 1;
+
+	/**
+	 * Constant copied from org.eclipse.compare.structuremergeviewer.Differencer.DELETION
+	 * in order to avoid UI dependencies introduced by the org.eclipse.compare bundle
+	 */
+	public static final int DELETION = 2;
+
+	/**
+	 * Constant copied from org.eclipse.compare.structuremergeviewer.Differencer.CHANGE
+	 * in order to avoid UI dependencies introduced by the org.eclipse.compare bundle
+	 */
+	public static final int CHANGE = 3;
+
+	/**
+	 * Constant copied from org.eclipse.compare.structuremergeviewer.Differencer.LEFT
+	 * in order to avoid UI dependencies introduced by the org.eclipse.compare bundle
+	 */
+	public static final int LEFT = 4;
+
+	/**
+	 * Constant copied from org.eclipse.compare.structuremergeviewer.Differencer.RIGHT
+	 * in order to avoid UI dependencies introduced by the org.eclipse.compare bundle
+	 */
+	public static final int RIGHT = 8;
+
+	/**
+	 * Corresponds to {@link RevCommit} object, but contains only those data
+	 * that are required by Synchronize view Change Set
+	 */
+	public static class Commit {
+		private int direction;
+
+		private String shortMessage;
+
+		private AbbreviatedObjectId commitId;
+
+		private Date commitDate;
+
+		private String authorName;
+
+		private String committerName;
+
+		private Map<String, Change> children;
+
+		private Commit() {
+			// reduce the visibility of the default constructor
+		}
+
+		/**
+		 * Indicates if this commit is incoming or outgoing. Returned value
+		 * corresponds to org.eclipse.compare.structuremergeviewer.Differencer#LEFT for incoming and
+		 * org.eclipse.compare.structuremergeviewer.Differencer#RIGHT for outgoing changes
+		 *
+		 * @return change direction
+		 */
+		public int getDirection() {
+			return direction;
+		}
+
+		/**
+		 * @return commit id
+		 */
+		public AbbreviatedObjectId getId() {
+			return commitId;
+		}
+
+		/**
+		 * @return commit author
+		 */
+		public String getAuthorName() {
+			return authorName;
+		}
+
+		/**
+		 * @return the committer name
+		 */
+		public String getCommitterName() {
+			return committerName;
+		}
+
+		/**
+		 * @return commit date
+		 */
+		public Date getCommitDate() {
+			return commitDate;
+		}
+
+		/**
+		 * @return commit short message
+		 */
+		public String getShortMessage() {
+			return shortMessage;
+		}
+
+		/**
+		 * @return list of changes made by this commit or {@code null} when
+		 *         commit doesn't have any changes
+		 */
+		public Map<String, Change> getChildren() {
+			return children;
+		}
+
+		/**
+		 * Disposes nested resources
+		 */
+		public void dispose() {
+			children.clear();
+		}
+
+	}
+
+	/**
+	 * Describes single tree or blob change in commit.
+	 */
+	public static class Change {
+		int kind;
+
+		String name;
+
+		AbbreviatedObjectId objectId;
+
+		AbbreviatedObjectId commitId;
+
+		AbbreviatedObjectId remoteCommitId;
+
+		AbbreviatedObjectId remoteObjectId;
+
+		Change() {
+			// reduce the visibility of the default constructor
+		}
+
+		/**
+		 * Describes if this change is incoming/outgoing addition, deletion or
+		 * change.
+		 *
+		 * It uses static values of LEFT, RIGHT, ADDITION, DELETION, CHANGE from
+		 * org.eclipse.compare.structuremergeviewer.Differencer class.
+		 *
+		 * @return kind
+		 */
+		public int getKind() {
+			return kind;
+		}
+
+		/**
+		 * @return object name
+		 */
+		public String getName() {
+			return name;
+		}
+
+		/**
+		 * @return id of commit containing this change
+		 */
+		public AbbreviatedObjectId getCommitId() {
+			return commitId;
+		}
+
+		/**
+		 * @return id of parent commit
+		 */
+		public AbbreviatedObjectId getRemoteCommitId() {
+			return remoteCommitId;
+		}
+
+		/**
+		 * @return object id
+		 */
+		public AbbreviatedObjectId getObjectId() {
+			return objectId;
+		}
+
+		/**
+		 * @return remote object id
+		 */
+		public AbbreviatedObjectId getRemoteObjectId() {
+			return remoteObjectId;
+		}
+
+		@Override
+		public int hashCode() {
+			final int prime = 31;
+			int result = 1;
+			result = prime * result
+					+ ((objectId == null) ? 0 : objectId.hashCode());
+			result = prime
+					* result
+					+ ((remoteObjectId == null) ? 0 : remoteObjectId.hashCode());
+			return result;
+		}
+
+		@Override
+		public boolean equals(Object obj) {
+			if (this == obj)
+				return true;
+			if (obj == null)
+				return false;
+			if (getClass() != obj.getClass())
+				return false;
+			Change other = (Change) obj;
+			if (objectId == null) {
+				if (other.objectId != null)
+					return false;
+			} else if (!objectId.equals(other.objectId))
+				return false;
+			if (remoteObjectId == null) {
+				if (other.remoteObjectId != null)
+					return false;
+			} else if (!remoteObjectId.equals(other.remoteObjectId))
+				return false;
+			return true;
+		}
+
+		@Override
+		public String toString() {
+			StringBuilder change = new StringBuilder("Change("); //$NON-NLS-1$
+			if ((kind & LEFT) != 0)
+				change.append("OUTGOING "); //$NON-NLS-1$
+			else
+				// should be RIGHT
+				change.append("INCOMING "); //$NON-NLS-1$
+			if ((kind & ADDITION) != 0)
+				change.append("ADDITION "); //$NON-NLS-1$
+			else if ((kind & DELETION) != 0)
+				change.append("DELETION "); //$NON-NLS-1$
+			else
+				// should be CHANGE
+				change.append("CHANGE "); //$NON-NLS-1$
+
+			change.append(name);
+			change.append(";\n\tcurrent objectId: "); //$NON-NLS-1$
+			change.append(getObjectId(objectId));
+			change.append(";\n\tparent objectId: "); //$NON-NLS-1$
+			change.append(getObjectId(remoteObjectId));
+			change.append(";\n\tcurrent commit: "); //$NON-NLS-1$
+			change.append(getObjectId(commitId));
+			change.append(";\n\tparent commit: "); //$NON-NLS-1$
+			change.append(getObjectId(remoteCommitId));
+			change.append("\n)"); //$NON-NLS-1$
+
+			return change.toString();
+		}
+
+		private String getObjectId(AbbreviatedObjectId object) {
+			if (object != null)
+				return object.toObjectId().getName();
+			else
+				return ObjectId.zeroId().getName();
+		}
+
+	}
+
+	static final AbbreviatedObjectId ZERO_ID = AbbreviatedObjectId
+			.fromObjectId(zeroId());
+
+	/**
+	 * Scans given {@code repo} and build list of commits between two given
+	 * RevCommit objectId's. Each commit contains list of changed resources
+	 *
+	 * @param repo
+	 *            repository that should be scanned
+	 * @param srcId
+	 *            RevCommit id that git history traverse will start from
+	 * @param dstId
+	 *            RevCommit id that git history traverse will end
+	 * @param pathFilter
+	 *            path filter definition or {@code null} when all paths should
+	 *            be included
+	 * @return list of {@link Commit} object's between {@code srcId} and
+	 *         {@code dstId}
+	 * @throws IOException
+	 */
+	public static List<Commit> build(Repository repo, ObjectId srcId,
+			ObjectId dstId, TreeFilter pathFilter) throws IOException {
+		if (dstId.equals(srcId))
+			return new ArrayList<Commit>(0);
+
+		final RevWalk rw = new RevWalk(repo);
+
+		final RevFlag localFlag = rw.newFlag("local"); //$NON-NLS-1$
+		final RevFlag remoteFlag = rw.newFlag("remote"); //$NON-NLS-1$
+		final RevFlagSet allFlags = new RevFlagSet();
+		allFlags.add(localFlag);
+		allFlags.add(remoteFlag);
+		rw.carry(allFlags);
+
+		RevCommit srcCommit = rw.parseCommit(srcId);
+		srcCommit.add(localFlag);
+		rw.markStart(srcCommit);
+		srcCommit = null; // free not needed resources
+
+		RevCommit dstCommit = rw.parseCommit(dstId);
+		dstCommit.add(remoteFlag);
+		rw.markStart(dstCommit);
+		dstCommit = null; // free not needed resources
+
+		if (pathFilter != null)
+			rw.setTreeFilter(pathFilter);
+
+		List<Commit> result = new ArrayList<Commit>();
+		for (RevCommit revCommit : rw) {
+			if (revCommit.hasAll(allFlags))
+				break;
+
+			Commit commit = new Commit();
+			commit.shortMessage = revCommit.getShortMessage();
+			commit.commitId = AbbreviatedObjectId.fromObjectId(revCommit);
+			commit.authorName = revCommit.getAuthorIdent().getName();
+			commit.committerName = revCommit.getCommitterIdent().getName();
+			commit.commitDate = revCommit.getAuthorIdent().getWhen();
+
+			RevCommit actualCommit, parentCommit;
+			if (revCommit.has(localFlag)) {
+				actualCommit = revCommit;
+				parentCommit = getParentCommit(revCommit);
+				commit.direction = RIGHT;
+			} else if (revCommit.has(remoteFlag)) {
+				actualCommit = getParentCommit(revCommit);
+				parentCommit = revCommit;
+				commit.direction = LEFT;
+			} else
+				throw new GitCommitsModelDirectionException();
+
+			commit.children = getChangedObjects(repo, actualCommit,
+					parentCommit, pathFilter, commit.direction);
+
+			if (commit.children != null)
+				result.add(commit);
+		}
+		rw.dispose();
+
+		return result;
+	}
+
+	private static RevCommit getParentCommit(RevCommit commit) {
+		if (commit.getParents().length > 0)
+			return commit.getParents()[0];
+		else
+			return null;
+	}
+
+	private static Map<String, Change> getChangedObjects(Repository repo,
+			RevCommit parentCommit, RevCommit remoteCommit,
+			TreeFilter pathFilter, final int direction) throws IOException {
+		final TreeWalk tw = new TreeWalk(repo);
+		addTreeFilter(tw, parentCommit);
+		addTreeFilter(tw, remoteCommit);
+
+		tw.setRecursive(true);
+		if (pathFilter == null)
+			tw.setFilter(ANY_DIFF);
+		else
+			tw.setFilter(AndTreeFilter.create(ANY_DIFF, pathFilter));
+
+		final int localTreeId = direction == LEFT ? 1 : 0;
+		final int remoteTreeId = direction == LEFT ? 0 : 1;
+		final Map<String, Change> result = new HashMap<String, GitCommitsModelCache.Change>();
+		final AbbreviatedObjectId actualCommit = getAbbreviatedObjectId(parentCommit);
+		final AbbreviatedObjectId remoteCommitAbb = getAbbreviatedObjectId(remoteCommit);
+
+		MutableObjectId idBuf = new MutableObjectId();
+		while (tw.next()) {
+			Change change = new Change();
+			change.commitId = actualCommit;
+			change.remoteCommitId = remoteCommitAbb;
+			change.name = tw.getNameString();
+			tw.getObjectId(idBuf, localTreeId);
+			change.objectId = AbbreviatedObjectId.fromObjectId(idBuf);
+			tw.getObjectId(idBuf, remoteTreeId);
+			change.remoteObjectId = AbbreviatedObjectId.fromObjectId(idBuf);
+
+			calculateAndSetChangeKind(direction, change);
+
+			result.put(tw.getPathString(), change);
+		}
+		tw.release();
+
+		return result.size() > 0 ? result : null;
+	}
+
+	private static void addTreeFilter(TreeWalk tw, RevCommit commit)
+			throws IOException {
+		if (commit != null)
+			tw.addTree(commit.getTree());
+		else
+			tw.addTree(new EmptyTreeIterator());
+	}
+
+	private static AbbreviatedObjectId getAbbreviatedObjectId(RevCommit commit) {
+		if (commit != null)
+			return AbbreviatedObjectId.fromObjectId(commit);
+		else
+			return ZERO_ID;
+	}
+
+	static void calculateAndSetChangeKind(final int direction, Change change) {
+		if (ZERO_ID.equals(change.objectId)) { // missing locally
+			change.objectId = null; // clear zero id;
+			if (direction == LEFT)
+				change.kind = direction | ADDITION;
+			else // should be Differencer.RIGHT
+				change.kind = direction | DELETION;
+		} else if (ZERO_ID.equals(change.remoteObjectId)) { // missing remotely
+			change.remoteObjectId = null; // clear zero id;
+			if (direction == LEFT)
+				change.kind = direction | DELETION;
+			else // should be Differencer.RIGHT
+				change.kind = direction | ADDITION;
+		} else
+			change.kind = direction | CHANGE;
+	}
+
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitCommitsModelDirectionException.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitCommitsModelDirectionException.java
new file mode 100644
index 0000000..ff1f00f
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitCommitsModelDirectionException.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (C) 2012, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.synchronize;
+
+/**
+ * Thrown when commit direction can't be determined during
+ * {@link GitCommitsModelCache#build(org.eclipse.jgit.lib.Repository, org.eclipse.jgit.lib.ObjectId, org.eclipse.jgit.lib.ObjectId, org.eclipse.jgit.treewalk.filter.TreeFilter)}
+ */
+public class GitCommitsModelDirectionException extends RuntimeException {
+
+	/**
+	 *
+	 */
+	private static final long serialVersionUID = 7867729888561453855L;
+
+	/**
+	 * Creates exception instance with default message
+	 */
+	public GitCommitsModelDirectionException() {
+		super("Unknown commit direction"); //$NON-NLS-1$
+	}
+
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitRemoteFile.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitRemoteFile.java
new file mode 100644
index 0000000..94ca2c0
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitRemoteFile.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright (C) 2011, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.synchronize;
+
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.storage.CommitBlobStorage;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.team.core.TeamException;
+
+class GitRemoteFile extends GitRemoteResource {
+
+	private final Repository repo;
+
+	GitRemoteFile(Repository repo, RevCommit commitId, ObjectId objectId,
+			String path) {
+		super(commitId, objectId, path);
+		this.repo = repo;
+	}
+
+	public boolean isContainer() {
+		return false;
+	}
+
+	@Override
+	protected void fetchContents(IProgressMonitor monitor) throws TeamException {
+		CommitBlobStorage content = new CommitBlobStorage(repo, getPath(),
+				getObjectId(), getCommitId());
+		try {
+			setContents(content.getContents(), monitor);
+		} catch (CoreException e) {
+			Activator.error("", e); //$NON-NLS-1$
+		}
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (obj == this)
+			return true;
+
+		if (obj instanceof GitRemoteFile) {
+			GitRemoteFile that = (GitRemoteFile) obj;
+
+			return getPath().equals(that.getPath())
+					&& getObjectId().equals(that.getObjectId());
+		}
+
+		return false;
+	}
+
+	@Override
+	public IStorage getStorage(IProgressMonitor monitor) throws TeamException {
+		return new CommitBlobStorage(repo, getCachePath(), getObjectId(),
+				getCommitId());
+	}
+
+	@Override
+	public int hashCode() {
+		return getObjectId().hashCode() ^ getPath().hashCode();
+	}
+
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitRemoteFolder.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitRemoteFolder.java
new file mode 100644
index 0000000..4dbaeb7
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitRemoteFolder.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (C) 2011, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.synchronize;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.egit.core.internal.CoreText;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.team.core.TeamException;
+import org.eclipse.team.core.variants.IResourceVariant;
+
+class GitRemoteFolder extends GitRemoteResource {
+
+	private final GitSyncObjectCache cachedData;
+	private final Repository repo;
+
+	/**
+	 *
+	 * @param repo
+	 * @param cachedData
+	 * @param commitId
+	 * @param objectId
+	 *            given object sha-1 id or {@code null} if this object doesn't
+	 *            exist in remote
+	 * @param path
+	 */
+	GitRemoteFolder(Repository repo, GitSyncObjectCache cachedData,
+			RevCommit commitId, ObjectId objectId, String path) {
+		super(commitId, objectId, path);
+		this.repo = repo;
+		this.cachedData = cachedData;
+	}
+
+	public boolean isContainer() {
+		return true;
+	}
+
+	@Override
+	protected void fetchContents(IProgressMonitor monitor) throws TeamException {
+		// should be never used on folder
+	}
+
+	public boolean equals(Object object) {
+		if (object == this)
+			return true;
+
+		if (object instanceof GitRemoteFolder) {
+			GitRemoteFolder that = (GitRemoteFolder) object;
+
+			return getPath().equals(that.getPath())
+					&& getObjectId().equals(that.getObjectId());
+		}
+
+		return false;
+	}
+
+	public int hashCode() {
+		return getObjectId().hashCode() ^ getPath().hashCode();
+	}
+
+	GitRemoteResource[] members(IProgressMonitor monitor) {
+		Collection<GitSyncObjectCache> members = cachedData.members();
+		if (members == null || members.size() == 0)
+			return new GitRemoteResource[0];
+
+		List<IResourceVariant> result = new ArrayList<IResourceVariant>();
+
+		monitor.beginTask(
+				NLS.bind(CoreText.GitRemoteFolder_fetchingMembers, getPath()),
+				cachedData.membersCount());
+		try {
+			for (GitSyncObjectCache member : members) {
+				ThreeWayDiffEntry diffEntry = member.getDiffEntry();
+				String memberPath = diffEntry.getPath();
+
+				GitRemoteResource obj;
+				ObjectId id = diffEntry.getRemoteId().toObjectId();
+				if (diffEntry.isTree())
+					obj = new GitRemoteFolder(repo, member, getCommitId(), id,
+							memberPath);
+				else
+					obj = new GitRemoteFile(repo, getCommitId(), id, memberPath);
+
+				result.add(obj);
+				monitor.worked(1);
+			}
+		} finally {
+			monitor.done();
+		}
+
+		return result.toArray(new GitRemoteResource[result.size()]);
+	}
+
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitRemoteResource.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitRemoteResource.java
new file mode 100644
index 0000000..e11d1f9
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitRemoteResource.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (C) 2011, 2012 Dariusz Luksza <dariusz@luksza.org> and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.synchronize;
+
+import static org.eclipse.jgit.lib.ObjectId.zeroId;
+
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.PersonIdent;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.team.core.variants.CachedResourceVariant;
+
+abstract class GitRemoteResource extends CachedResourceVariant {
+
+	private final String path;
+
+	private final RevCommit commitId;
+
+	private final ObjectId objectId;
+
+
+	GitRemoteResource(RevCommit commitId, ObjectId objectId, String path) {
+		this.path = path;
+		this.objectId = objectId;
+		this.commitId = commitId;
+	}
+
+	public String getName() {
+		int lastSeparator = path.lastIndexOf("/"); //$NON-NLS-1$
+		return path.substring(lastSeparator + 1, path.length());
+	}
+
+	public String getContentIdentifier() {
+		if (commitId == null)
+			return ""; //$NON-NLS-1$
+
+		StringBuilder s = new StringBuilder();
+		s.append(commitId.abbreviate(7).name());
+		s.append("..."); //$NON-NLS-1$
+
+		PersonIdent authorIdent = commitId.getAuthorIdent();
+		if (authorIdent != null) {
+			s.append(" ("); //$NON-NLS-1$
+			s.append(authorIdent.getName());
+			s.append(")"); //$NON-NLS-1$
+		}
+		return s.toString();
+	}
+
+	public byte[] asBytes() {
+		return getObjectId().name().getBytes();
+	}
+
+	@Override
+	protected String getCachePath() {
+		return path;
+	}
+
+	@Override
+	protected String getCacheId() {
+		return "org.eclipse.egit"; //$NON-NLS-1$
+	}
+
+	boolean exists() {
+		return commitId != null;
+	}
+
+	RevCommit getCommitId() {
+		return commitId;
+	}
+
+	/**
+	 * @return object id, or {code {@link RevCommit#zeroId()} if object doesn't
+	 *         exist in repository
+	 */
+	ObjectId getObjectId() {
+		return objectId != null ? objectId : zeroId();
+	}
+
+	String getPath() {
+		return path;
+	}
+
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitRemoteResourceVariantTree.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitRemoteResourceVariantTree.java
new file mode 100644
index 0000000..9f393eb
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitRemoteResourceVariantTree.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2010 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Dariusz Luksza <dariusz@luksza.org>
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.synchronize;
+
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeData;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeDataSet;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.team.core.variants.SessionResourceVariantByteStore;
+
+class GitRemoteResourceVariantTree extends GitResourceVariantTree {
+
+	GitRemoteResourceVariantTree(GitSyncCache cache, GitSynchronizeDataSet data) {
+		super(new SessionResourceVariantByteStore(), cache, data);
+	}
+
+	@Override
+	protected ObjectId getObjectId(ThreeWayDiffEntry diffEntry) {
+		return diffEntry.getRemoteId().toObjectId();
+	}
+
+	@Override
+	protected RevCommit getCommitId(GitSynchronizeData gsd) {
+		return gsd.getSrcRevCommit();
+	}
+
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitResourceVariantComparator.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitResourceVariantComparator.java
new file mode 100644
index 0000000..fa03422
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitResourceVariantComparator.java
@@ -0,0 +1,152 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Dariusz Luksza <dariusz@luksza.org>
+ *     Daniel Megert <daniel_megert@ch.ibm.com> - remove unnecessary @SuppressWarnings
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.synchronize;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeDataSet;
+import org.eclipse.team.core.TeamException;
+import org.eclipse.team.core.variants.IResourceVariant;
+import org.eclipse.team.core.variants.IResourceVariantComparator;
+
+class GitResourceVariantComparator implements IResourceVariantComparator {
+
+	private final GitSynchronizeDataSet gsd;
+
+	GitResourceVariantComparator(GitSynchronizeDataSet dataSet) {
+		gsd = dataSet;
+	}
+
+	@SuppressWarnings("resource")
+	public boolean compare(IResource local, IResourceVariant remote) {
+		if (!local.exists() || remote == null) {
+			return false;
+		}
+
+		if (local instanceof IFile) {
+			if (remote.isContainer()) {
+				return false;
+			}
+
+			InputStream stream = null;
+			InputStream remoteStream = null;
+			try {
+				remoteStream = remote.getStorage(new NullProgressMonitor())
+						.getContents();
+				stream = getLocal(local);
+				byte[] remoteBytes = new byte[8096];
+				byte[] bytes = new byte[8096];
+
+				int remoteRead = remoteStream.read(remoteBytes);
+				int read = stream.read(bytes);
+				if (remoteRead != read) {
+					return false;
+				}
+
+				while (Arrays.equals(bytes, remoteBytes)) {
+					remoteRead = remoteStream.read(remoteBytes);
+					read = stream.read(bytes);
+					if (remoteRead != read) {
+						// didn't read the same amount, it's uneven
+						return false;
+					} else if (read == -1) {
+						// both at EOF, check their contents
+						return Arrays.equals(bytes, remoteBytes);
+					}
+				}
+			} catch (IOException e) {
+				logException(e);
+				return false;
+			} catch (CoreException e) {
+				logException(e);
+				return false;
+			} finally {
+				closeStream(stream);
+				closeStream(remoteStream);
+			}
+		} else if (local instanceof IContainer) {
+			GitRemoteFolder gitVariant = (GitRemoteFolder) remote;
+			if (!remote.isContainer() || (local.exists() ^ gitVariant.exists()))
+				return false;
+
+			return local.getLocation().toString().equals(gitVariant.getCachePath());
+		}
+		return false;
+	}
+
+	public boolean compare(IResourceVariant base, IResourceVariant remote) {
+		GitRemoteResource gitBase = (GitRemoteResource) base;
+		GitRemoteResource gitRemote = (GitRemoteResource) remote;
+
+		boolean exists = gitBase.exists() && gitRemote.exists();
+		boolean equalType = !(gitBase.isContainer() ^ gitRemote.isContainer());
+		boolean equalSha1 = gitBase.getObjectId().getName()
+				.equals(gitRemote.getObjectId().getName());
+
+		return equalType && exists && equalSha1;
+	}
+
+	public boolean isThreeWay() {
+		return true;
+	}
+
+	private InputStream getLocal(IResource resource) throws CoreException {
+		if (gsd.getData(resource.getProject().getName()).shouldIncludeLocal())
+			return getSynchronizedFile(resource).getContents();
+		else
+			try {
+				if (resource.getType() == IResource.FILE)
+					return getSynchronizedFile(resource).getContents();
+				else
+					return new ByteArrayInputStream(new byte[0]);
+			} catch (TeamException e) {
+				throw new CoreException(e.getStatus());
+			}
+	}
+
+	private IFile getSynchronizedFile(IResource resource) throws CoreException {
+		IFile file = ((IFile) resource);
+		if (!file.isSynchronized(0))
+			file.refreshLocal(0, null);
+
+		return file;
+	}
+
+	private void logException(Exception e) {
+		IStatus error = new Status(IStatus.ERROR, Activator.getPluginId(),
+				e.getMessage(), e);
+		Activator.getDefault().getLog().log(error);
+	}
+
+	private void closeStream(InputStream stream) {
+		if (stream != null) {
+			try {
+				stream.close();
+			} catch (IOException e) {
+				logException(e);
+			}
+		}
+	}
+
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitResourceVariantTree.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitResourceVariantTree.java
new file mode 100644
index 0000000..3359da0
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitResourceVariantTree.java
@@ -0,0 +1,159 @@
+/*******************************************************************************
+ * Copyright (c) 2010 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Dariusz Luksza <dariusz@luksza.org>
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.synchronize;
+
+import static org.eclipse.egit.core.internal.util.ResourceUtil.isNonWorkspace;
+import static org.eclipse.jgit.lib.ObjectId.zeroId;
+import static org.eclipse.jgit.lib.Repository.stripWorkDir;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.WeakHashMap;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.SubMonitor;
+import org.eclipse.egit.core.internal.CoreText;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeData;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeDataSet;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.team.core.TeamException;
+import org.eclipse.team.core.variants.IResourceVariant;
+import org.eclipse.team.core.variants.ResourceVariantByteStore;
+import org.eclipse.team.core.variants.ResourceVariantTree;
+
+abstract class GitResourceVariantTree extends ResourceVariantTree {
+
+	private final GitSyncCache gitCache;
+
+	private final GitSynchronizeDataSet gsds;
+
+	private final Map<IResource, IResourceVariant> cache = new WeakHashMap<IResource, IResourceVariant>();
+
+
+	GitResourceVariantTree(ResourceVariantByteStore store,
+			GitSyncCache gitCache, GitSynchronizeDataSet gsds) {
+		super(store);
+		this.gsds = gsds;
+		this.gitCache = gitCache;
+	}
+
+	public IResource[] roots() {
+		Set<IResource> roots = new HashSet<IResource>();
+		for (GitSynchronizeData gsd : gsds)
+			if (gsd.getPathFilter() == null)
+				roots.addAll(gsd.getProjects());
+			else
+				for (IContainer container : gsd.getIncludedPaths())
+					roots.add(container.getProject());
+
+		return roots.toArray(new IResource[roots.size()]);
+	}
+
+	/**
+	 * Disposes all nested resources
+	 */
+	public void dispose() {
+		if (gsds != null)
+			gsds.dispose();
+
+		cache.clear();
+	}
+
+	@Override
+	protected IResourceVariant fetchVariant(IResource resource, int depth,
+			IProgressMonitor monitor) throws TeamException {
+		SubMonitor subMonitor = SubMonitor.convert(monitor);
+		if (resource == null || isNonWorkspace(resource)) {
+			subMonitor.done();
+			return null;
+		}
+
+		subMonitor.beginTask(NLS.bind(
+				CoreText.GitResourceVariantTree_fetchingVariant,
+				resource.getName()), IProgressMonitor.UNKNOWN);
+		try {
+			return fetchVariant(resource);
+		} finally {
+			subMonitor.done();
+		}
+	}
+
+	private IResourceVariant fetchVariant(IResource resource) {
+		if (gitCache == null)
+			return null;
+
+		if (cache.containsKey(resource))
+			return cache.get(resource);
+
+		GitSynchronizeData gsd = gsds.getData(resource.getProject());
+		if (gsd == null)
+			return null;
+
+		Repository repo = gsd.getRepository();
+		String path = getPath(resource, repo);
+
+		GitSyncObjectCache syncCache = gitCache.get(repo);
+		GitSyncObjectCache cachedData = syncCache.get(path);
+		if (cachedData == null)
+			return null;
+
+		IResourceVariant variant = null;
+		ObjectId objectId = getObjectId(cachedData.getDiffEntry());
+		if (!objectId.equals(zeroId())) {
+			if (resource.getType() == IResource.FILE)
+				variant = new GitRemoteFile(repo, getCommitId(gsd), objectId,
+						path);
+			else
+				variant = new GitRemoteFolder(repo, cachedData,
+						getCommitId(gsd), objectId, path);
+
+			cache.put(resource, variant);
+		}
+
+		return variant;
+	}
+
+	protected abstract ObjectId getObjectId(ThreeWayDiffEntry diffEntry);
+
+	protected abstract RevCommit getCommitId(GitSynchronizeData gsd);
+
+	@Override
+	protected IResourceVariant[] fetchMembers(IResourceVariant variant,
+			IProgressMonitor progress) throws TeamException {
+		if (variant == null || !(variant instanceof GitRemoteFolder))
+			return new IResourceVariant[0];
+
+		GitRemoteFolder gitVariant = (GitRemoteFolder) variant;
+
+		try {
+			return gitVariant.members(progress);
+		} finally {
+			progress.done();
+		}
+	}
+
+	public IResourceVariant getResourceVariant(final IResource resource)
+			throws TeamException {
+		return fetchVariant(resource, 0, null);
+	}
+
+	private String getPath(final IResource resource, Repository repo) {
+		return stripWorkDir(repo.getWorkTree(), resource.getLocation().toFile());
+	}
+
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitResourceVariantTreeSubscriber.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitResourceVariantTreeSubscriber.java
new file mode 100644
index 0000000..0226593
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitResourceVariantTreeSubscriber.java
@@ -0,0 +1,279 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2012 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Dariusz Luksza <dariusz@luksza.org>
+ *     François Rey - gracefully ignore linked resources
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.synchronize;
+
+import static org.eclipse.jgit.lib.Repository.stripWorkDir;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.egit.core.internal.CoreText;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeData;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeDataSet;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.treewalk.TreeWalk;
+import org.eclipse.team.core.TeamException;
+import org.eclipse.team.core.synchronize.SyncInfo;
+import org.eclipse.team.core.variants.IResourceVariant;
+import org.eclipse.team.core.variants.IResourceVariantComparator;
+import org.eclipse.team.core.variants.IResourceVariantTree;
+import org.eclipse.team.core.variants.ResourceVariantTreeSubscriber;
+
+/**
+ *
+ */
+public class GitResourceVariantTreeSubscriber extends
+		ResourceVariantTreeSubscriber {
+
+	/**
+	 * A resource variant tree of the remote branch(es).
+	 */
+	private GitRemoteResourceVariantTree remoteTree;
+
+	/**
+	 * A resource variant tree against HEAD.
+	 */
+	private GitBaseResourceVariantTree baseTree;
+
+	private GitSynchronizeDataSet gsds;
+
+	private IResource[] roots;
+
+	private GitSyncCache cache;
+
+	/**
+	 * @param data
+	 */
+	public GitResourceVariantTreeSubscriber(GitSynchronizeDataSet data) {
+		this.gsds = data;
+	}
+
+	/**
+	 * Initialize git subscriber. This method will pre-fetch data from git
+	 * repository. This approach will reduce number of {@link TreeWalk}'s
+	 * created during synchronization
+	 *
+	 * @param monitor
+	 */
+	public void init(IProgressMonitor monitor) {
+		monitor.beginTask(
+				CoreText.GitResourceVariantTreeSubscriber_fetchTaskName,
+				gsds.size());
+		try {
+			cache = GitSyncCache.getAllData(gsds, monitor);
+		} finally {
+			monitor.done();
+		}
+	}
+
+	@Override
+	public boolean isSupervised(IResource res) throws TeamException {
+		return IResource.FILE == res.getType()
+				&& gsds.contains(res.getProject()) && shouldBeIncluded(res);
+	}
+
+	/**
+	 * Returns all members of git repository (including those that are not
+	 * imported into workspace)
+	 *
+	 * @param res
+	 */
+	@Override
+	public IResource[] members(IResource res) throws TeamException {
+		if(res.getType() == IResource.FILE || !shouldBeIncluded(res))
+			return new IResource[0];
+
+		GitSynchronizeData gsd = gsds.getData(res.getProject());
+		Repository repo = gsd.getRepository();
+		GitSyncObjectCache repoCache = cache.get(repo);
+
+		Set<IResource> gitMembers = new HashSet<IResource>();
+		Map<String, IResource> allMembers = new HashMap<String, IResource>();
+
+		Set<GitSyncObjectCache> gitCachedMembers = new HashSet<GitSyncObjectCache>();
+		String path = stripWorkDir(repo.getWorkTree(), res.getLocation().toFile());
+		GitSyncObjectCache cachedMembers = repoCache.get(path);
+		if (cachedMembers != null) {
+			Collection<GitSyncObjectCache> members = cachedMembers.members();
+			if (members != null)
+				gitCachedMembers.addAll(members);
+		}
+		try {
+			for (IResource member : ((IContainer) res).members())
+				allMembers.put(member.getName(), member);
+
+			for (GitSyncObjectCache gitMember : gitCachedMembers) {
+				IResource member = allMembers.get(gitMember.getName());
+				if (member != null)
+					gitMembers.add(member);
+			}
+		} catch (CoreException e) {
+			throw TeamException.asTeamException(e);
+		}
+
+		return gitMembers.toArray(new IResource[gitMembers.size()]);
+	}
+
+	@Override
+	public void refresh(IResource[] resources, int depth,
+			IProgressMonitor monitor) throws TeamException {
+		for (IResource resource : resources) {
+			// check to see if there is a full refresh
+			if (resource.getType() == IResource.ROOT) {
+				// refresh entire cache
+				GitSyncCache newCache = GitSyncCache.getAllData(gsds, monitor);
+				cache.merge(newCache);
+				super.refresh(resources, depth, monitor);
+				return;
+			}
+		}
+
+		// not refreshing the workspace, locate and collect target resources
+		Map<GitSynchronizeData, Collection<String>> updateRequests = new HashMap<GitSynchronizeData, Collection<String>>();
+		for (IResource resource : resources) {
+			IProject project = resource.getProject();
+			GitSynchronizeData data = gsds.getData(project.getName());
+			if (data != null) {
+				RepositoryMapping mapping = RepositoryMapping
+						.getMapping(project);
+				// mapping may be null if the project has been closed
+				if (mapping != null) {
+					Collection<String> paths = updateRequests.get(data);
+					if (paths == null) {
+						paths = new ArrayList<String>();
+						updateRequests.put(data, paths);
+					}
+
+					String path = mapping.getRepoRelativePath(resource);
+					// null path may be returned, check for this
+					if (path == null)
+						// unknown, force a refresh of the whole repository
+						path = ""; //$NON-NLS-1$
+					paths.add(path);
+				}
+			}
+		}
+
+		// scan only the repositories that were affected
+		if (!updateRequests.isEmpty()) {
+			// refresh cache
+			GitSyncCache newCache = GitSyncCache.getAllData(updateRequests,
+					monitor);
+			cache.merge(newCache);
+		}
+
+		super.refresh(resources, depth, monitor);
+	}
+
+	@Override
+	public IResource[] roots() {
+		if (roots == null)
+			roots = gsds.getAllProjects();
+		IResource[] result = new IResource[roots.length];
+		System.arraycopy(roots, 0, result, 0, roots.length);
+		return result;
+	}
+
+	/**
+	 * @param data
+	 */
+	public void reset(GitSynchronizeDataSet data) {
+		gsds = data;
+
+		roots = null;
+		baseTree = null;
+		remoteTree = null;
+	}
+
+	/**
+	 * Disposes nested resources
+	 */
+	public void dispose() {
+		if (baseTree != null)
+			baseTree.dispose();
+		if (remoteTree != null)
+			remoteTree.dispose();
+		gsds.dispose();
+	}
+
+	@Override
+	public String getName() {
+		return CoreText.GitBranchResourceVariantTreeSubscriber_gitRepository;
+	}
+
+	@Override
+	public IResourceVariantComparator getResourceComparator() {
+		return new GitResourceVariantComparator(gsds);
+	}
+
+	@Override
+	protected IResourceVariantTree getBaseTree() {
+		if (baseTree == null)
+			baseTree = new GitBaseResourceVariantTree(cache, gsds);
+
+		return baseTree;
+	}
+
+	@Override
+	protected IResourceVariantTree getRemoteTree() {
+		if (remoteTree == null)
+			remoteTree = new GitRemoteResourceVariantTree(cache, gsds);
+
+		return remoteTree;
+	}
+
+	@Override
+	protected SyncInfo getSyncInfo(IResource local, IResourceVariant base,
+			IResourceVariant remote) throws TeamException {
+
+		Repository repo = gsds.getData(local.getProject()).getRepository();
+		SyncInfo info = new GitSyncInfo(local, base, remote,
+				getResourceComparator(), cache.get(repo), repo);
+
+		info.init();
+		return info;
+	}
+
+	private boolean shouldBeIncluded(IResource res) {
+		if (res == null || res.isLinked(IResource.CHECK_ANCESTORS))
+			return false;
+		final IProject proj = res.getProject();
+		if (proj == null)
+			return false;
+		final GitSynchronizeData d = gsds.getData(proj);
+		if (d == null)
+			return false;
+		final Set<IContainer> includedPaths = d.getIncludedPaths();
+		if (includedPaths == null)
+			return true;
+
+		IPath path = res.getLocation();
+		for (IContainer container : includedPaths)
+			if (container.getLocation().isPrefixOf(path))
+				return true;
+
+		return false;
+	}
+
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitSubscriberMergeContext.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitSubscriberMergeContext.java
new file mode 100644
index 0000000..cb885e5
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitSubscriberMergeContext.java
@@ -0,0 +1,209 @@
+/*******************************************************************************
+ * Copyright (C) 2010, 2013 Dariusz Luksza <dariusz@luksza.org> and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.synchronize;
+
+import java.io.IOException;
+import java.util.Collection;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.resources.mapping.ResourceTraversal;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.CoreText;
+import org.eclipse.egit.core.internal.indexdiff.GitResourceDeltaVisitor;
+import org.eclipse.egit.core.internal.indexdiff.IndexDiffCache;
+import org.eclipse.egit.core.internal.indexdiff.IndexDiffChangedListener;
+import org.eclipse.egit.core.internal.indexdiff.IndexDiffData;
+import org.eclipse.egit.core.internal.op.AddToIndexOperation;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeData;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeDataSet;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.team.core.TeamException;
+import org.eclipse.team.core.diff.IDiff;
+import org.eclipse.team.core.mapping.ISynchronizationScopeManager;
+import org.eclipse.team.core.subscribers.SubscriberMergeContext;
+
+/**
+ *
+ */
+public class GitSubscriberMergeContext extends SubscriberMergeContext {
+
+	private final GitSynchronizeDataSet gsds;
+
+	private final IndexDiffChangedListener indexChangeListener;
+
+	private final IResourceChangeListener resourceChangeListener;
+
+	private final GitResourceVariantTreeSubscriber subscriber;
+
+	/**
+	 * @param subscriber
+	 * @param manager
+	 * @param gsds
+	 */
+	public GitSubscriberMergeContext(final GitResourceVariantTreeSubscriber subscriber,
+			ISynchronizationScopeManager manager, GitSynchronizeDataSet gsds) {
+		super(subscriber, manager);
+		this.subscriber = subscriber;
+		this.gsds = gsds;
+
+
+		indexChangeListener = new IndexDiffChangedListener() {
+			public void indexDiffChanged(Repository repository,
+					IndexDiffData indexDiffData) {
+				handleRepositoryChange(repository);
+			}
+		};
+		resourceChangeListener = new IResourceChangeListener() {
+
+			public void resourceChanged(IResourceChangeEvent event) {
+				IResourceDelta delta = event.getDelta();
+				if (delta == null)
+					return;
+
+				handleResourceChange(delta);
+			}
+		};
+		IndexDiffCache indexDiffCache = Activator.getDefault().getIndexDiffCache();
+		if (indexDiffCache != null)
+			indexDiffCache.addIndexDiffChangedListener(indexChangeListener);
+
+		ResourcesPlugin.getWorkspace().addResourceChangeListener(resourceChangeListener);
+
+		initialize();
+	}
+
+	public void markAsMerged(IDiff node, boolean inSyncHint,
+			IProgressMonitor monitor) throws CoreException {
+		IResource resource = getDiffTree().getResource(node);
+		AddToIndexOperation operation = new AddToIndexOperation(
+				new IResource[] { resource });
+		operation.execute(monitor);
+	}
+
+	public void reject(IDiff diff, IProgressMonitor monitor)
+			throws CoreException {
+		// TODO Auto-generated method stub
+
+	}
+
+	/**
+	 * @return git synchronization data
+	 */
+	public GitSynchronizeDataSet getSyncData() {
+		return gsds;
+	}
+
+	@Override
+	protected void makeInSync(IDiff diff, IProgressMonitor monitor)
+			throws CoreException {
+		// TODO Auto-generated method stub
+
+	}
+
+	@Override
+	public void dispose() {
+		Activator activator = Activator.getDefault();
+		if (activator == null)
+			return;
+
+		IndexDiffCache indexDiffCache = activator.getIndexDiffCache();
+		if (indexDiffCache != null)
+			indexDiffCache.removeIndexDiffChangedListener(indexChangeListener);
+
+		ResourcesPlugin.getWorkspace().removeResourceChangeListener(resourceChangeListener);
+		subscriber.dispose();
+		super.dispose();
+	}
+
+	private void handleRepositoryChange(Repository which) {
+		boolean shouldRefresh = false;
+		for (GitSynchronizeData gsd : gsds) {
+			if (which.equals(gsd.getRepository())) {
+				updateRevs(gsd);
+				shouldRefresh = true;
+			}
+		}
+
+		if (!shouldRefresh)
+			return;
+
+		subscriber.reset(this.gsds);
+		ResourceTraversal[] traversals = getScopeManager().getScope()
+				.getTraversals();
+		try {
+			subscriber.refresh(traversals, new NullProgressMonitor());
+		} catch (TeamException e) {
+			Activator.logError(
+					CoreText.GitSubscriberMergeContext_FailedRefreshSyncView, e);
+		}
+	}
+
+	private void handleResourceChange(IResourceDelta delta) {
+		IResourceDelta[] children = delta.getAffectedChildren();
+		for (IResourceDelta resourceDelta : children) {
+			IResource resource = resourceDelta.getResource();
+			RepositoryMapping mapping = RepositoryMapping.getMapping(resource);
+			if (mapping == null)
+				continue;
+
+			scanDeltaAndRefresh(mapping, resourceDelta);
+		}
+	}
+
+	private void scanDeltaAndRefresh(RepositoryMapping mapping,
+			IResourceDelta delta) {
+		Repository repo = mapping.getRepository();
+		GitResourceDeltaVisitor visitor = new GitResourceDeltaVisitor(repo);
+		try {
+			delta.accept(visitor);
+			Collection<IFile> files = visitor.getFileResourcesToUpdate();
+			if (files != null && files.isEmpty())
+				return;
+
+			for (GitSynchronizeData gsd : gsds) {
+				if (repo.equals(gsd.getRepository()))
+					refreshResources(files);
+			}
+		} catch (CoreException e) {
+			Activator.logError(e.getMessage(), e);
+		}
+	}
+
+	private void refreshResources(Collection<IFile> resources) {
+		IResource[] files = resources.toArray(new IResource[resources
+				.size()]);
+		try {
+			subscriber.refresh(files, IResource.DEPTH_ONE,
+					new NullProgressMonitor());
+		} catch (final CoreException e) {
+			Activator.logError(
+					CoreText.GitSubscriberMergeContext_FailedRefreshSyncView, e);
+		}
+	}
+
+	private void updateRevs(GitSynchronizeData gsd) {
+		try {
+			gsd.updateRevs();
+		} catch (IOException e) {
+			Activator.logError(
+					CoreText.GitSubscriberMergeContext_FailedUpdateRevs, e);
+			return;
+		}
+	}
+
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitSubscriberResourceMappingContext.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitSubscriberResourceMappingContext.java
new file mode 100644
index 0000000..c5641f2
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitSubscriberResourceMappingContext.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.synchronize;
+
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeDataSet;
+import org.eclipse.team.core.subscribers.SubscriberResourceMappingContext;
+
+/**
+ *
+ */
+public class GitSubscriberResourceMappingContext extends
+		SubscriberResourceMappingContext {
+
+	private final GitSynchronizeDataSet data;
+
+	/**
+	 * @param subscriber
+	 * @param data
+	 */
+	public GitSubscriberResourceMappingContext(
+			GitResourceVariantTreeSubscriber subscriber,
+			GitSynchronizeDataSet data) {
+		super(subscriber, true);
+		this.data = data;
+	}
+
+	/**
+	 * @return git synchronize data set
+	 */
+	public GitSynchronizeDataSet getSyncData() {
+		return data;
+	}
+
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitSyncCache.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitSyncCache.java
new file mode 100644
index 0000000..3858df9
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitSyncCache.java
@@ -0,0 +1,219 @@
+/*******************************************************************************
+ * Copyright (C) 2011, Dariusz Luksza <dariusz@luksza.org> and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.synchronize;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.SubMonitor;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeData;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeDataSet;
+import org.eclipse.jgit.dircache.DirCache;
+import org.eclipse.jgit.dircache.DirCacheIterator;
+import org.eclipse.jgit.lib.AbbreviatedObjectId;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.treewalk.EmptyTreeIterator;
+import org.eclipse.jgit.treewalk.FileTreeIterator;
+import org.eclipse.jgit.treewalk.TreeWalk;
+import org.eclipse.jgit.treewalk.filter.AndTreeFilter;
+import org.eclipse.jgit.treewalk.filter.NotIgnoredFilter;
+import org.eclipse.jgit.treewalk.filter.OrTreeFilter;
+import org.eclipse.jgit.treewalk.filter.PathFilter;
+import org.eclipse.jgit.treewalk.filter.TreeFilter;
+
+/**
+ * Simple and thin tree cache for git meta data about resources in repository.
+ */
+class GitSyncCache {
+
+	private final Map<File, GitSyncObjectCache> cache;
+
+	public static GitSyncCache getAllData(GitSynchronizeDataSet gsds,
+			IProgressMonitor monitor) {
+		Map<GitSynchronizeData, Collection<String>> updateRequests = new HashMap<GitSynchronizeData, Collection<String>>();
+		for (GitSynchronizeData data : gsds)
+			updateRequests.put(data, Collections.<String> emptyList());
+		return getAllData(updateRequests, monitor);
+	}
+
+	public static GitSyncCache getAllData(
+			Map<GitSynchronizeData, Collection<String>> updateRequests,
+			IProgressMonitor monitor) {
+		GitSyncCache cache = new GitSyncCache();
+		SubMonitor m = SubMonitor.convert(monitor, updateRequests.size());
+
+		for (Entry<GitSynchronizeData, Collection<String>> entry : updateRequests
+				.entrySet()) {
+			cache.merge(getAllData(entry.getKey(), entry.getValue()));
+			m.worked(1);
+		}
+
+		m.done();
+		return cache;
+	}
+
+	private static GitSyncCache getAllData(GitSynchronizeData gsd,
+			Collection<String> paths) {
+		GitSyncCache cache = new GitSyncCache();
+		TreeFilter filter = paths.isEmpty() ? null : createPathFilter(paths);
+
+		Repository repo = gsd.getRepository();
+		ObjectId baseTree = getTree(gsd.getSrcRevCommit());
+		ObjectId remoteTree = getTree(gsd.getDstRevCommit());
+		GitSyncObjectCache repoCache = cache.put(repo, baseTree, remoteTree);
+
+		TreeFilter gsdFilter = gsd.getPathFilter();
+		if (filter == null)
+			loadDataFromGit(gsd, gsdFilter, repoCache);
+		else if (gsdFilter == null)
+			loadDataFromGit(gsd, filter, repoCache);
+		else
+			loadDataFromGit(gsd, AndTreeFilter.create(filter, gsdFilter),
+					repoCache);
+		return cache;
+	}
+
+	private static TreeFilter createPathFilter(Collection<String> paths) {
+		// do not use PathFilterGroup to create the filter, see bug 362430
+		List<TreeFilter> filters = new ArrayList<TreeFilter>(paths.size());
+		for (String path : paths) {
+			if (path.length() == 0)
+				return null;
+			filters.add(PathFilter.create(path));
+		}
+		if (filters.size() == 1)
+			return filters.get(0);
+		return OrTreeFilter.create(filters);
+	}
+
+	private static void loadDataFromGit(GitSynchronizeData gsd,
+			TreeFilter filter, GitSyncObjectCache repoCache) {
+		Repository repo = gsd.getRepository();
+		TreeWalk tw = new TreeWalk(repo);
+		if (filter != null)
+			tw.setFilter(filter);
+
+		try {
+			// setup local tree
+			FileTreeIterator fti = null;
+			if (gsd.shouldIncludeLocal()) {
+				fti = new FileTreeIterator(repo);
+				tw.addTree(fti);
+				if (filter != null)
+					tw.setFilter(AndTreeFilter.create(filter,
+							new NotIgnoredFilter(0)));
+				else
+					tw.setFilter(new NotIgnoredFilter(0));
+			} else if (gsd.getSrcRevCommit() != null)
+				tw.addTree(gsd.getSrcRevCommit().getTree());
+			else
+				tw.addTree(new EmptyTreeIterator());
+
+			// setup base tree
+			if (gsd.getCommonAncestorRev() != null)
+				tw.addTree(gsd.getCommonAncestorRev().getTree());
+			else
+				tw.addTree(new EmptyTreeIterator());
+
+			// setup remote tree
+			if (gsd.getDstRevCommit() != null)
+				tw.addTree(gsd.getDstRevCommit().getTree());
+			else
+				tw.addTree(new EmptyTreeIterator());
+
+			DirCacheIterator dci = null;
+			if (fti != null) {
+				dci = new DirCacheIterator(DirCache.read(repo));
+				tw.addTree(dci);
+				fti.setDirCacheIterator(tw, 3);
+			}
+			List<ThreeWayDiffEntry> diffEntrys = ThreeWayDiffEntry.scan(tw);
+			tw.release();
+
+			for (ThreeWayDiffEntry diffEntry : diffEntrys)
+				repoCache.addMember(diffEntry);
+		} catch (Exception e) {
+			Activator.logError(e.getMessage(), e);
+		}
+	}
+
+	private static ObjectId getTree(RevCommit commit) {
+		if (commit != null)
+			return commit.getTree();
+		else {
+			return ObjectId.zeroId();
+		}
+	}
+
+	private GitSyncCache() {
+		cache = new HashMap<File, GitSyncObjectCache>();
+	}
+
+	/**
+	 * @param repo
+	 *            instance of {@link Repository} for with mapping should be
+	 *            obtained
+	 * @return instance of {@link GitSyncObjectCache} connected associated with
+	 *         given repository or {@code null} when such mapping wasn't found
+	 */
+	public GitSyncObjectCache get(Repository repo) {
+		return cache.get(repo.getDirectory());
+	}
+
+	public void merge(GitSyncCache newCache) {
+		for (Entry<File, GitSyncObjectCache> entry : newCache.cache.entrySet()) {
+			File key = entry.getKey();
+			if (cache.containsKey(key))
+				cache.get(key).merge(entry.getValue());
+			else
+				cache.put(key, entry.getValue());
+		}
+	}
+
+	@Override
+	public String toString() {
+		StringBuilder builder = new StringBuilder();
+		for (Entry<File, GitSyncObjectCache> entry : cache.entrySet())
+			builder.append(entry.getKey().getPath())
+					.append(": ").append(entry.getValue()); //$NON-NLS-1$
+
+		return builder.toString();
+	}
+
+	/**
+	 * Create mapping for given repository and returns object associated with
+	 * this repository. Any other mapping will be overwritten.
+	 *
+	 * @param repo
+	 * @param remoteTree
+	 * @param baseTree
+	 * @return new mapping object associated with given {@link Repository}
+	 */
+	private GitSyncObjectCache put(Repository repo, ObjectId baseTree,
+			ObjectId remoteTree) {
+		ThreeWayDiffEntry entry = new ThreeWayDiffEntry();
+		entry.baseId = AbbreviatedObjectId.fromObjectId(baseTree);
+		entry.remoteId = AbbreviatedObjectId.fromObjectId(remoteTree);
+		GitSyncObjectCache objectCache = new GitSyncObjectCache("", entry); //$NON-NLS-1$
+		cache.put(repo.getDirectory(), objectCache);
+
+		return objectCache;
+	}
+
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitSyncInfo.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitSyncInfo.java
new file mode 100644
index 0000000..1f60450
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitSyncInfo.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.synchronize;
+
+import static org.eclipse.jgit.lib.Repository.stripWorkDir;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.egit.core.internal.synchronize.ThreeWayDiffEntry.ChangeType;
+import org.eclipse.egit.core.internal.synchronize.ThreeWayDiffEntry.Direction;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.team.core.TeamException;
+import org.eclipse.team.core.synchronize.SyncInfo;
+import org.eclipse.team.core.variants.IResourceVariant;
+import org.eclipse.team.core.variants.IResourceVariantComparator;
+
+class GitSyncInfo extends SyncInfo {
+
+	private final GitSyncObjectCache cache;
+	private final Repository repo;
+
+	public GitSyncInfo(IResource local, IResourceVariant base,
+			IResourceVariant remote, IResourceVariantComparator comparator,
+			GitSyncObjectCache cache, Repository repo) {
+		super(local, base, remote, comparator);
+		this.repo = repo;
+		this.cache = cache;
+	}
+
+	@Override
+	protected int calculateKind() throws TeamException {
+		if (cache.membersCount() == 0)
+			return IN_SYNC;
+
+		String path;
+		if (getLocal() != null && getLocal().getLocation() != null)
+			path = stripWorkDir(repo.getWorkTree(), getLocal().getLocation().toFile());
+		else if (getRemote() != null)
+			path = ((GitRemoteResource)getRemote()).getPath();
+		else if (getBase() != null)
+			path = ((GitRemoteResource)getBase()).getPath();
+		else
+			return IN_SYNC;
+
+		GitSyncObjectCache obj = cache.get(path);
+		if (obj == null)
+			return IN_SYNC;
+
+		int direction;
+		Direction gitDirection = obj.getDiffEntry().getDirection();
+		if (gitDirection == Direction.INCOMING)
+			direction = INCOMING;
+		else if (gitDirection == Direction.OUTGOING)
+			direction = OUTGOING;
+		else
+			direction = CONFLICTING;
+
+		ChangeType changeType = obj.getDiffEntry().getChangeType();
+
+		if (changeType == ChangeType.MODIFY)
+			return direction | CHANGE;
+		if (changeType == ChangeType.ADD)
+			return direction | ADDITION;
+		if (changeType == ChangeType.DELETE)
+			return direction | DELETION;
+
+		return IN_SYNC;
+	}
+
+	@Override
+	public boolean equals(Object other) {
+		return super.equals(other);
+	}
+
+	@Override
+	public int hashCode() {
+		return super.hashCode();
+	}
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitSyncObjectCache.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitSyncObjectCache.java
new file mode 100644
index 0000000..cca60fe
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/GitSyncObjectCache.java
@@ -0,0 +1,193 @@
+/*******************************************************************************
+ * Copyright (C) 2011, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.synchronize;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.eclipse.egit.core.internal.CoreText;
+import org.eclipse.egit.core.internal.synchronize.ThreeWayDiffEntry.ChangeType;
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Thin cache object. It contains list of object members, object name and
+ * {@link ThreeWayDiffEntry} data.
+ */
+class GitSyncObjectCache {
+
+	private final String name;
+
+	private final ThreeWayDiffEntry diffEntry;
+
+	private Map<String, GitSyncObjectCache> members;
+
+	/**
+	 * Creates node and leaf element
+	 *
+	 * @param name
+	 *            entry name
+	 * @param diffEntry
+	 *            entry meta data
+	 */
+	GitSyncObjectCache(String name, ThreeWayDiffEntry diffEntry) {
+		this.name = name;
+		this.diffEntry = diffEntry;
+	}
+
+	/**
+	 * @return name of this object
+	 */
+	public String getName() {
+		return name;
+	}
+
+	/**
+	 *
+	 * @return entry meta data
+	 */
+	public ThreeWayDiffEntry getDiffEntry() {
+		return diffEntry;
+	}
+
+	/**
+	 * Store given {@code entry} in cache. It assumes that parent of
+	 * {@code entry} is already in cache, if not {@link RuntimeException} will
+	 * be thrown.
+	 *
+	 * @param entry
+	 *            that should be stored in cache
+	 * @throws RuntimeException
+	 *             when cannot find parent of given {@code entry} in cache
+	 */
+	public void addMember(ThreeWayDiffEntry entry) {
+		String memberPath = entry.getPath();
+
+		if (members == null)
+			members = new HashMap<String, GitSyncObjectCache>();
+
+		int start = -1;
+		Map<String, GitSyncObjectCache> parent = members;
+		int separatorIdx = memberPath.indexOf("/"); //$NON-NLS-1$
+		while (separatorIdx > 0) {
+			String key = memberPath.substring(start + 1, separatorIdx);
+			GitSyncObjectCache cacheObject = parent.get(key);
+			if (cacheObject == null)
+				throw new RuntimeException(NLS.bind(
+						CoreText.GitSyncObjectCache_noData, key));
+
+			start = separatorIdx;
+			separatorIdx = memberPath.indexOf("/", separatorIdx + 1); //$NON-NLS-1$
+			if (cacheObject.members == null)
+				cacheObject.members = new HashMap<String, GitSyncObjectCache>();
+
+			parent = cacheObject.members;
+		}
+
+		String newName;
+		if (start > 0)
+			newName = memberPath.substring(start + 1);
+		else
+			newName = memberPath;
+
+		GitSyncObjectCache obj = new GitSyncObjectCache(newName, entry);
+		parent.put(newName, obj);
+	}
+
+	/**
+	 * @param childPath
+	 *            repository relative path of entry that should be obtained
+	 * @return cached object, or {@code null} when cache doen't contain object
+	 *         for given path
+	 */
+	public GitSyncObjectCache get(String childPath) {
+		if (childPath.length() == 0)
+			return this;
+		if (childPath
+				.substring(childPath.lastIndexOf("/") + 1, childPath.length()).equals(name)) //$NON-NLS-1$
+			return this;
+		if (members == null)
+			return null;
+
+		int start = -1;
+		Map<String, GitSyncObjectCache> parent = members;
+		int separatorIdx = childPath.indexOf("/"); //$NON-NLS-1$
+		while (separatorIdx > 0) {
+			String key = childPath.substring(start + 1, separatorIdx);
+
+			GitSyncObjectCache childObject = parent.get(key);
+			if (childObject == null)
+				return null;
+
+			start = separatorIdx;
+			separatorIdx = childPath.indexOf("/", separatorIdx + 1); //$NON-NLS-1$
+			parent = childObject.members;
+			if (parent == null)
+				return null;
+		}
+
+		return parent.get(childPath.subSequence(
+				childPath.lastIndexOf("/") + 1, childPath.length())); //$NON-NLS-1$
+	}
+
+	/**
+	 * @return number of cached members
+	 */
+	public int membersCount() {
+		return members != null ? members.size() : 0;
+	}
+
+	/**
+	 * @return list of all cached members or {@code null} when there this object
+	 *         doesn't contain members
+	 */
+	public Collection<GitSyncObjectCache> members() {
+		return members != null ? members.values() : null;
+	}
+
+	@Override
+	public String toString() {
+		StringBuilder builder = new StringBuilder();
+		builder.append("entry: ").append(diffEntry).append("\n"); //$NON-NLS-1$ //$NON-NLS-2$
+		if (members != null) {
+			builder.append("members: "); //$NON-NLS-1$
+			for (GitSyncObjectCache obj : members.values())
+				builder.append(obj.toString()).append("\n"); //$NON-NLS-1$
+		}
+
+		return builder.toString();
+	}
+
+	void merge(GitSyncObjectCache value) {
+		if (value.members != null) {
+			if (members == null)
+				members = new HashMap<String, GitSyncObjectCache>();
+			else
+				for (Entry<String, GitSyncObjectCache> entry : members
+						.entrySet())
+					if (!value.members.containsKey(entry.getKey()))
+						entry.getValue().diffEntry.changeType = ChangeType.IN_SYNC;
+
+			for (Entry<String, GitSyncObjectCache> entry : value.members
+					.entrySet()) {
+				String key = entry.getKey();
+				if (members.containsKey(key))
+					members.get(key).merge(entry.getValue());
+				else
+					members.put(key, entry.getValue());
+			}
+		} else if (members != null)
+			for (GitSyncObjectCache obj : members.values())
+				obj.diffEntry.changeType = ChangeType.IN_SYNC;
+		else // we should be on leaf entry, just update the change type value
+			diffEntry.changeType = value.diffEntry.changeType;
+	}
+
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/StagedChangeCache.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/StagedChangeCache.java
new file mode 100644
index 0000000..f7abcf8
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/StagedChangeCache.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (C) 2011, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.synchronize;
+
+import static org.eclipse.egit.core.internal.synchronize.GitCommitsModelCache.RIGHT;
+import static org.eclipse.egit.core.internal.synchronize.GitCommitsModelCache.calculateAndSetChangeKind;
+import static org.eclipse.jgit.lib.Constants.HEAD;
+import static org.eclipse.jgit.lib.FileMode.MISSING;
+import static org.eclipse.jgit.lib.FileMode.TREE;
+import static org.eclipse.jgit.lib.ObjectId.zeroId;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.synchronize.GitCommitsModelCache.Change;
+import org.eclipse.jgit.dircache.DirCacheIterator;
+import org.eclipse.jgit.lib.AbbreviatedObjectId;
+import org.eclipse.jgit.lib.MutableObjectId;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.treewalk.EmptyTreeIterator;
+import org.eclipse.jgit.treewalk.TreeWalk;
+
+/**
+ * Builds list of changes in git staging area.
+ */
+public class StagedChangeCache {
+
+	/**
+	 * @param repo
+	 *            repository which should be scanned
+	 * @return list of changes in git staging area
+	 */
+	public static Map<String, Change> build(Repository repo) {
+		TreeWalk tw = new TreeWalk(repo);
+		try {
+			tw.addTree(new DirCacheIterator(repo.readDirCache()));
+			ObjectId headId = repo.resolve(HEAD);
+			RevCommit headCommit;
+			if (headId != null)
+				headCommit = new RevWalk(repo).parseCommit(headId);
+			else
+				headCommit = null;
+
+			AbbreviatedObjectId commitId;
+			if (headCommit != null) {
+				tw.addTree(headCommit.getTree());
+				commitId = AbbreviatedObjectId.fromObjectId(headCommit);
+			} else {
+				tw.addTree(new EmptyTreeIterator());
+				commitId =AbbreviatedObjectId.fromObjectId(zeroId());
+			}
+
+			tw.setRecursive(true);
+			headCommit = null;
+
+			MutableObjectId idBuf = new MutableObjectId();
+			Map<String, Change> result = new HashMap<String, Change>();
+			while(tw.next()) {
+				if (!shouldIncludeEntry(tw))
+					continue;
+
+				Change change = new Change();
+				change.name = tw.getNameString();
+				change.remoteCommitId = commitId;
+
+				tw.getObjectId(idBuf, 0);
+				change.objectId = AbbreviatedObjectId.fromObjectId(idBuf);
+				tw.getObjectId(idBuf, 1);
+				change.remoteObjectId = AbbreviatedObjectId.fromObjectId(idBuf);
+
+				calculateAndSetChangeKind(RIGHT, change);
+
+				result.put(tw.getPathString(), change);
+			}
+			tw.release();
+
+			return result;
+		} catch (IOException e) {
+			Activator.error(e.getMessage(), e);
+			return new HashMap<String, Change>(0);
+		}
+	}
+
+	private static boolean shouldIncludeEntry(TreeWalk tw) {
+		final int mHead = tw.getRawMode(1);
+		final int mCache = tw.getRawMode(0);
+
+		return mHead == MISSING.getBits() // initial add to cache
+				|| mCache == MISSING.getBits() // removed from cache
+				|| (mHead != mCache || (mCache != TREE.getBits() && !tw
+						.idEqual(1, 0))); // modified
+	}
+
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/ThreeWayDiffEntry.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/ThreeWayDiffEntry.java
new file mode 100644
index 0000000..ddef7ee
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/ThreeWayDiffEntry.java
@@ -0,0 +1,226 @@
+/*******************************************************************************
+ * Copyright (C) 2011, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.synchronize;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jgit.lib.AbbreviatedObjectId;
+import org.eclipse.jgit.lib.FileMode;
+import org.eclipse.jgit.lib.MutableObjectId;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.treewalk.TreeWalk;
+
+/**
+ * Based on {@link org.eclipse.jgit.diff.DiffEntry}. Represents change to a file
+ * with additional information about change direction.
+ */
+public final class ThreeWayDiffEntry {
+
+	/** Magical SHA1 used for file adds or deletes */
+	private static final AbbreviatedObjectId A_ZERO = AbbreviatedObjectId
+			.fromObjectId(ObjectId.zeroId());
+
+	/** General type of change a single file-level patch describes. */
+	public static enum ChangeType {
+		/** Add a new file to the project */
+		ADD,
+
+		/** Modify an existing file in the project (content and/or mode) */
+		MODIFY,
+
+		/** Delete an existing file from the project */
+		DELETE,
+
+		/** Resource is in sync */
+		IN_SYNC;
+	}
+
+	/** Change direction */
+	public static enum Direction {
+		/**
+		 *
+		 */
+		INCOMING,
+
+		/**
+		 *
+		 */
+		OUTGOING,
+
+		/** */
+		CONFLICTING;
+	}
+
+	ThreeWayDiffEntry() {
+		// reduce the visibility of the default constructor
+	}
+
+	/**
+	 * Converts the TreeWalk into TreeWayDiffEntry headers.
+	 *
+	 * @param walk
+	 *            the TreeWalk to walk through. Must have exactly three trees in
+	 *            this order: local, base and remote and can't be recursive.
+	 * @return headers describing the changed file.
+	 * @throws IOException
+	 *             the repository cannot be accessed.
+	 * @throws IllegalArgumentException
+	 *             when {@code walk} doen't have exactly three trees, or when
+	 *             {@code walk} is recursive
+	 */
+	public static List<ThreeWayDiffEntry> scan(TreeWalk walk)
+			throws IOException {
+		if (walk.getTreeCount() != 3 && walk.getTreeCount() != 4)
+			throw new IllegalArgumentException(
+					"TreeWalk need to have three or four trees"); //$NON-NLS-1$
+		if (walk.isRecursive())
+			throw new IllegalArgumentException(
+					"TreeWalk shouldn't be recursive."); //$NON-NLS-1$
+
+		List<ThreeWayDiffEntry> r = new ArrayList<ThreeWayDiffEntry>();
+		MutableObjectId idBuf = new MutableObjectId();
+		while (walk.next()) {
+			ThreeWayDiffEntry e = new ThreeWayDiffEntry();
+
+			walk.getObjectId(idBuf, 0);
+			e.localId = AbbreviatedObjectId.fromObjectId(idBuf);
+
+			walk.getObjectId(idBuf, 1);
+			e.baseId = AbbreviatedObjectId.fromObjectId(idBuf);
+
+			walk.getObjectId(idBuf, 2);
+			e.remoteId = AbbreviatedObjectId.fromObjectId(idBuf);
+
+			boolean localSameAsBase = e.localId.equals(e.baseId);
+			if (!A_ZERO.equals(e.localId) && localSameAsBase
+					&& e.baseId.equals(e.remoteId))
+				continue;
+
+			e.path = walk.getPathString();
+			boolean localIsMissing = walk.getFileMode(0) == FileMode.MISSING;
+			boolean baseIsMissing = walk.getFileMode(1) == FileMode.MISSING;
+			boolean remoteIsMissing = walk.getFileMode(2) == FileMode.MISSING;
+
+			if (localIsMissing || baseIsMissing || remoteIsMissing) {
+				if (!localIsMissing && baseIsMissing && remoteIsMissing) {
+					e.direction = Direction.OUTGOING;
+					e.changeType = ChangeType.ADD;
+				} else if (localIsMissing && baseIsMissing && !remoteIsMissing) {
+					e.direction = Direction.INCOMING;
+					e.changeType = ChangeType.ADD;
+				} else if (!localIsMissing && !baseIsMissing && remoteIsMissing) {
+					e.direction = Direction.INCOMING;
+					e.changeType = ChangeType.DELETE;
+				} else if (localIsMissing && !baseIsMissing && !remoteIsMissing) {
+					e.direction = Direction.OUTGOING;
+					e.changeType = ChangeType.DELETE;
+				} else {
+					e.direction = Direction.CONFLICTING;
+					e.changeType = ChangeType.MODIFY;
+				}
+			} else {
+				if (localSameAsBase && !e.localId.equals(e.remoteId))
+					e.direction = Direction.INCOMING;
+				else if (e.remoteId.equals(e.baseId)
+						&& !e.remoteId.equals(e.localId))
+					e.direction = Direction.OUTGOING;
+				else
+					e.direction = Direction.CONFLICTING;
+
+				e.changeType = ChangeType.MODIFY;
+			}
+
+			r.add(e);
+			if (walk.isSubtree()) {
+				e.isTree = true;
+				walk.enterSubtree();
+			}
+		}
+
+		return r;
+	}
+
+	ChangeType changeType;
+
+	AbbreviatedObjectId baseId;
+
+	AbbreviatedObjectId remoteId;
+
+	private String path;
+
+	private Direction direction;
+
+	private AbbreviatedObjectId localId;
+
+	private boolean isTree = false;
+
+	/**
+	 * @return base id
+	 */
+	public AbbreviatedObjectId getBaseId() {
+		return baseId;
+	}
+
+	/**
+	 * @return path
+	 */
+	public String getPath() {
+		return path;
+	}
+
+	/**
+	 * @return {@code true} if entry represents tree, {@code false} otherwise
+	 */
+	public boolean isTree() {
+		return isTree;
+	}
+
+	/** @return the type of change this patch makes on {@link #getPath()} */
+	public ChangeType getChangeType() {
+		return changeType;
+	}
+
+	/**
+	 * Get the old object id from the <code>index</code>.
+	 *
+	 * @return the object id; null if there is no index line
+	 */
+	public AbbreviatedObjectId getLocalId() {
+		return localId;
+	}
+
+	/**
+	 * Get the new object id from the <code>index</code>.
+	 *
+	 * @return the object id; null if there is no index line
+	 */
+	public AbbreviatedObjectId getRemoteId() {
+		return remoteId;
+	}
+
+	/**
+	 * @return direction
+	 */
+	public Direction getDirection() {
+		return direction;
+	}
+
+	@Override
+	public String toString() {
+		StringBuilder buf = new StringBuilder();
+		buf.append("ThreeDiffEntry["); //$NON-NLS-1$
+		buf.append(changeType).append(" ").append(path); //$NON-NLS-1$
+		buf.append("]"); //$NON-NLS-1$
+
+		return buf.toString();
+	}
+
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/WorkingTreeChangeCache.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/WorkingTreeChangeCache.java
new file mode 100644
index 0000000..cf13968
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/WorkingTreeChangeCache.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (C) 2011, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.synchronize;
+
+import static org.eclipse.egit.core.internal.synchronize.GitCommitsModelCache.RIGHT;
+import static org.eclipse.egit.core.internal.synchronize.GitCommitsModelCache.calculateAndSetChangeKind;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.synchronize.GitCommitsModelCache.Change;
+import org.eclipse.jgit.dircache.DirCacheIterator;
+import org.eclipse.jgit.lib.AbbreviatedObjectId;
+import org.eclipse.jgit.lib.MutableObjectId;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.treewalk.FileTreeIterator;
+import org.eclipse.jgit.treewalk.TreeWalk;
+import org.eclipse.jgit.treewalk.filter.IndexDiffFilter;
+
+/**
+ * Builds list of working tree changes.
+ */
+public class WorkingTreeChangeCache {
+
+	/**
+	 * @param repo
+	 *            with should be scanned
+	 * @return list of changes in working tree
+	 */
+	public static Map<String, Change> build(Repository repo) {
+		TreeWalk tw = new TreeWalk(repo);
+		try {
+			int fileNth = tw.addTree(new FileTreeIterator(repo));
+			int cacheNth = tw.addTree(new DirCacheIterator(repo.readDirCache()));
+			tw.setFilter(new IndexDiffFilter(cacheNth, fileNth));
+			tw.setRecursive(true);
+
+			Map<String, Change> result = new HashMap<String, Change>();
+			MutableObjectId idBuf = new MutableObjectId();
+			while (tw.next()) {
+				Change change = new Change();
+				change.name = tw.getNameString();
+				tw.getObjectId(idBuf, 0);
+				change.objectId = AbbreviatedObjectId.fromObjectId(idBuf);
+				tw.getObjectId(idBuf, 1);
+				change.remoteObjectId = AbbreviatedObjectId.fromObjectId(idBuf);
+				calculateAndSetChangeKind(RIGHT, change);
+
+				result.put(tw.getPathString(), change);
+			}
+			tw.release();
+
+			return result;
+		} catch (IOException e) {
+			Activator.error(e.getMessage(), e);
+			return new HashMap<String, GitCommitsModelCache.Change>(0);
+		}
+	}
+
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/dto/GitSynchronizeData.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/dto/GitSynchronizeData.java
new file mode 100644
index 0000000..40b39f5
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/dto/GitSynchronizeData.java
@@ -0,0 +1,334 @@
+/*******************************************************************************
+ * Copyright (C) 2010, 2011 Dariusz Luksza <dariusz@luksza.org> and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.synchronize.dto;
+
+import static org.eclipse.core.runtime.Assert.isNotNull;
+import static org.eclipse.egit.core.internal.RevUtils.getCommonAncestor;
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_BRANCH_SECTION;
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_MERGE;
+import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_REMOTE;
+import static org.eclipse.jgit.lib.Constants.R_HEADS;
+import static org.eclipse.jgit.lib.Constants.R_REMOTES;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.ObjectWalk;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
+import org.eclipse.jgit.treewalk.filter.TreeFilter;
+
+/**
+ * Simple data transfer object containing all necessary information for
+ * launching synchronization
+ */
+public class GitSynchronizeData {
+
+	private static final IWorkspaceRoot ROOT = ResourcesPlugin.getWorkspace()
+					.getRoot();
+
+	/**
+	 * Matches all strings that start from R_HEADS
+	 */
+	public static final Pattern BRANCH_NAME_PATTERN = Pattern.compile("^" + R_HEADS + ".*?"); //$NON-NLS-1$ //$NON-NLS-2$
+
+	private final boolean includeLocal;
+
+	private final Repository repo;
+
+	private final String srcRemote;
+
+	private final String dstRemote;
+
+	private final String srcMerge;
+
+	private final String dstMerge;
+
+	private RevCommit srcRevCommit;
+
+	private RevCommit dstRevCommit;
+
+	private RevCommit ancestorRevCommit;
+
+	private final Set<IProject> projects;
+
+	private final String repoParentPath;
+
+	private final String srcRev;
+
+	private final String dstRev;
+
+	private TreeFilter pathFilter;
+
+	private Set<IContainer> includedPaths;
+
+	private static class RemoteConfig {
+		final String remote;
+		final String merge;
+		public RemoteConfig(String remote, String merge) {
+			this.remote = remote;
+			this.merge = merge;
+		}
+	}
+
+	/**
+	 * Constructs {@link GitSynchronizeData} object
+	 *
+	 * @param repository
+	 * @param srcRev
+	 * @param dstRev
+	 * @param includeLocal
+	 *            <code>true</code> if local changes should be included in
+	 *            comparison
+	 * @throws IOException
+	 */
+	public GitSynchronizeData(Repository repository, String srcRev,
+			String dstRev, boolean includeLocal) throws IOException {
+		isNotNull(repository);
+		isNotNull(srcRev);
+		isNotNull(dstRev);
+		repo = repository;
+		this.srcRev = srcRev;
+		this.dstRev = dstRev;
+		this.includeLocal = includeLocal;
+
+		RemoteConfig srcRemoteConfig = extractRemoteName(srcRev);
+		RemoteConfig dstRemoteConfig = extractRemoteName(dstRev);
+
+		srcRemote = srcRemoteConfig.remote;
+		srcMerge = srcRemoteConfig.merge;
+
+		dstRemote = dstRemoteConfig.remote;
+		dstMerge = dstRemoteConfig.merge;
+
+		repoParentPath = repo.getDirectory().getParentFile().getAbsolutePath();
+
+		projects = new HashSet<IProject>();
+		final IProject[] workspaceProjects = ROOT.getProjects();
+		for (IProject project : workspaceProjects) {
+			RepositoryMapping mapping = RepositoryMapping.getMapping(project);
+			if (mapping != null && mapping.getRepository() == repo)
+				projects.add(project);
+		}
+		updateRevs();
+	}
+
+	/**
+	 * Recalculates source, destination and ancestor Rev commits
+	 *
+	 * @throws IOException
+	 */
+	public void updateRevs() throws IOException {
+		ObjectWalk ow = new ObjectWalk(repo);
+		try {
+			srcRevCommit = getCommit(srcRev, ow);
+			dstRevCommit = getCommit(dstRev, ow);
+		} finally {
+			ow.release();
+		}
+
+		if (this.dstRevCommit != null && this.srcRevCommit != null)
+			this.ancestorRevCommit = getCommonAncestor(repo, this.srcRevCommit,
+					this.dstRevCommit);
+		else
+			this.ancestorRevCommit = null;
+	}
+
+	/**
+	 * @return instance of repository that should be synchronized
+	 */
+	public Repository getRepository() {
+		return repo;
+	}
+
+	/**
+	 * @return name of source remote or {@code null} when source branch is not a
+	 *         remote branch
+	 */
+	public String getSrcRemoteName() {
+		return srcRemote;
+	}
+
+	/**
+	 * @return ref specification of destination merge branch
+	 */
+	public String getDstMerge() {
+		return dstMerge;
+	}
+
+	/**
+	 * @return ref specification of source merge branch
+	 */
+	public String getSrcMerge() {
+		return srcMerge;
+	}
+
+	/**
+	 * @return name of destination remote or {@code null} when destination
+	 *         branch is not a remote branch
+	 */
+	public String getDstRemoteName() {
+		return dstRemote;
+	}
+
+	/**
+	 * @return synchronize source rev name
+	 */
+	public RevCommit getSrcRevCommit() {
+		return srcRevCommit;
+	}
+
+	/**
+	 * @return synchronize destination rev name
+	 */
+	public RevCommit getDstRevCommit() {
+		return dstRevCommit;
+	}
+
+	/**
+	 * @return list of project's that are connected with this repository
+	 */
+	public Set<IProject> getProjects() {
+		return Collections.unmodifiableSet(projects);
+	}
+
+	/**
+	 * @param file
+	 * @return <true> if given {@link File} is contained by this repository
+	 */
+	public boolean contains(File file) {
+		return file.getAbsoluteFile().toString().startsWith(repoParentPath);
+	}
+
+	/**
+	 * @return <code>true</code> if local changes should be included in
+	 *         comparison
+	 */
+	public boolean shouldIncludeLocal() {
+		return includeLocal;
+	}
+
+	/**
+	 * @return common ancestor commit
+	 */
+	public RevCommit getCommonAncestorRev() {
+		return ancestorRevCommit;
+	}
+
+	/**
+	 * @param includedPaths
+	 *            list of containers to be synchronized
+	 */
+	public void setIncludedPaths(Set<IContainer> includedPaths) {
+		this.includedPaths = includedPaths;
+		Set<String> paths = new HashSet<String>();
+		RepositoryMapping rm = RepositoryMapping.findRepositoryMapping(repo);
+		for (IContainer container : includedPaths) {
+			String repoRelativePath = rm.getRepoRelativePath(container);
+			if (repoRelativePath.length() > 0)
+				paths.add(repoRelativePath);
+		}
+
+		if (!paths.isEmpty())
+			pathFilter = PathFilterGroup.createFromStrings(paths);
+	}
+
+	/**
+	 * @return set of included paths or {@code null} when all paths should be
+	 *         included
+	 */
+	public Set<IContainer> getIncludedPaths() {
+		return includedPaths;
+	}
+
+	/**
+	 * Disposes all nested resources
+	 */
+	public void dispose() {
+		if (projects != null)
+			projects.clear();
+		if (includedPaths != null)
+			includedPaths.clear();
+	}
+
+	/**
+	 * @return instance of {@link TreeFilter} when synchronization was launched
+	 *         from nested node (like folder) or {@code null} otherwise
+	 */
+	public TreeFilter getPathFilter() {
+		return pathFilter;
+	}
+
+	/**
+	 * @return synchronization source rev
+	 */
+	public String getSrcRev() {
+		return srcRev;
+	}
+
+	/**
+	 * @return synchronization destination rev
+	 */
+	public String getDstRev() {
+		return dstRev;
+	}
+
+	private RemoteConfig extractRemoteName(String rev) {
+		if (rev.contains(R_REMOTES)) {
+			String remoteWithBranchName = rev.replaceAll(R_REMOTES, ""); //$NON-NLS-1$
+			int firstSeparator = remoteWithBranchName.indexOf("/"); //$NON-NLS-1$
+
+			String remote = remoteWithBranchName.substring(0, firstSeparator);
+			String name = remoteWithBranchName.substring(firstSeparator + 1,
+					remoteWithBranchName.length());
+
+			return new RemoteConfig(remote, R_HEADS + name);
+		} else {
+			String realName;
+			Ref ref;
+			try {
+				ref = repo.getRef(rev);
+			} catch (IOException e) {
+				ref = null;
+			}
+			if (ref != null && ref.isSymbolic())
+				realName = ref.getTarget().getName();
+			else
+				realName = rev;
+			String name = BRANCH_NAME_PATTERN.matcher(realName).replaceAll(""); //$NON-NLS-1$
+			String remote = repo.getConfig().getString(CONFIG_BRANCH_SECTION,
+					name, CONFIG_KEY_REMOTE);
+			String merge = repo.getConfig().getString(CONFIG_BRANCH_SECTION,
+					name, CONFIG_KEY_MERGE);
+
+			return new RemoteConfig(remote, merge);
+		}
+	}
+
+	private RevCommit getCommit(String rev, ObjectWalk ow) throws IOException {
+		if (rev.length() > 0) {
+			ObjectId id = repo.resolve(rev);
+			return id != null ? ow.parseCommit(id) : null;
+		} else
+			return null;
+	}
+
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/dto/GitSynchronizeDataSet.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/dto/GitSynchronizeDataSet.java
new file mode 100644
index 0000000..80cc543
--- /dev/null
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/synchronize/dto/GitSynchronizeDataSet.java
@@ -0,0 +1,166 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.core.internal.synchronize.dto;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.resources.IProject;
+
+/**
+ *
+ */
+public class GitSynchronizeDataSet implements Iterable<GitSynchronizeData> {
+
+	private boolean containsFolderLevelSynchronizationRequest = false;
+
+	private final Set<GitSynchronizeData> gsdSet;
+
+	private final Map<String, GitSynchronizeData> projectMapping;
+
+	private final boolean forceFetch;
+
+	/**
+	 * Constructs GitSynchronizeDataSet.
+	 */
+	public GitSynchronizeDataSet() {
+		this(false);
+	}
+
+	/**
+	 * Constructs GitSynchronizeDataSet.
+	 *
+	 * @param forceFetch
+	 *            {@code true} for forcing fetch action before synchronization
+	 */
+	public GitSynchronizeDataSet(boolean forceFetch) {
+		this.forceFetch = forceFetch;
+		gsdSet = new HashSet<GitSynchronizeData>();
+		projectMapping = new HashMap<String, GitSynchronizeData>();
+	}
+
+	/**
+	 * Constructs GitSynchronizeDataSet and adds given element to set.
+	 *
+	 * @param data
+	 */
+	public GitSynchronizeDataSet(GitSynchronizeData data) {
+		this();
+		add(data);
+	}
+
+	/**
+	 * @param data
+	 */
+	public void add(GitSynchronizeData data) {
+		gsdSet.add(data);
+		if (data.getIncludedPaths() != null
+				&& data.getIncludedPaths().size() > 0)
+			containsFolderLevelSynchronizationRequest = true;
+
+		for (IProject proj : data.getProjects()) {
+			projectMapping.put(proj.getName(), data);
+		}
+	}
+
+	/**
+	 * @param project
+	 * @return <code>true</code> if project has corresponding data
+	 */
+	public boolean contains(IProject project) {
+		return projectMapping.containsKey(project.getName());
+	}
+
+	/**
+	 * @return {@code true} when at least one {@link GitSynchronizeData} is
+	 *         configured to include changes only for particular folder,
+	 *         {@code false} otherwise
+	 */
+	public boolean containsFolderLevelSynchronizationRequest() {
+		return containsFolderLevelSynchronizationRequest;
+	}
+
+	/**
+	 * @return number of {@link GitSynchronizeData} that are included in this
+	 *         set
+	 */
+	public int size() {
+		return gsdSet.size();
+	}
+
+	/**
+	 * @param projectName
+	 * @return <code>null</code> if project does not have corresponding data
+	 */
+	public GitSynchronizeData getData(String projectName) {
+		return projectMapping.get(projectName);
+	}
+
+	/**
+	 * @param project
+	 * @return <code>null</code> if project does not have corresponding data
+	 */
+	public GitSynchronizeData getData(IProject project) {
+		return projectMapping.get(project.getName());
+	}
+
+	public Iterator<GitSynchronizeData> iterator() {
+		return gsdSet.iterator();
+	}
+
+	/**
+	 * @return list of all resources
+	 */
+	public IProject[] getAllProjects() {
+		Set<IProject> resource = new HashSet<IProject>();
+		for (GitSynchronizeData data : gsdSet) {
+			resource.addAll(data.getProjects());
+		}
+		return resource.toArray(new IProject[resource.size()]);
+	}
+
+
+	/**
+	 * @return {@code true} when fetch action should be forced before
+	 *         synchronization, {@code false} otherwise.
+	 */
+	public boolean forceFetch() {
+		return forceFetch;
+	}
+
+
+	/**
+	 * Disposes all nested resources
+	 */
+	public void dispose() {
+		if (projectMapping != null)
+			projectMapping.clear();
+
+		if (gsdSet != null)
+			for (GitSynchronizeData gsd : gsdSet)
+				gsd.dispose();
+
+	}
+
+	@Override
+	public String toString() {
+		StringBuilder builder = new StringBuilder();
+
+		for (GitSynchronizeData data : gsdSet) {
+			builder.append(data.getRepository().getWorkTree());
+			builder.append(" "); //$NON-NLS-1$
+		}
+
+		return builder.toString();
+	}
+
+}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/trace/GitTraceLocation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/trace/GitTraceLocation.java
index d1929af..d4e94d9 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/trace/GitTraceLocation.java
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/trace/GitTraceLocation.java
@@ -10,7 +10,7 @@
  *******************************************************************************/
 package org.eclipse.egit.core.internal.trace;
 
-import org.eclipse.egit.core.Activator;
+import org.eclipse.egit.core.internal.Activator;
 import org.eclipse.osgi.service.debug.DebugOptions;
 import org.eclipse.osgi.service.debug.DebugTrace;
 
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/util/ProjectUtil.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/util/ProjectUtil.java
index 72286f6..2f75e38 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/util/ProjectUtil.java
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/util/ProjectUtil.java
@@ -34,9 +34,9 @@
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.CoreText;
-import org.eclipse.egit.core.project.RepositoryMapping;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.CoreText;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.lib.RepositoryCache.FileKey;
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/util/ResourceUtil.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/util/ResourceUtil.java
index c5ac13d..4bb82b7 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/util/ResourceUtil.java
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/util/ResourceUtil.java
@@ -32,8 +32,8 @@
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.project.RepositoryMapping;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
 import org.eclipse.jgit.lib.Repository;
 
 /**
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/AddToIndexOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/AddToIndexOperation.java
deleted file mode 100644
index 054532a..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/AddToIndexOperation.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2010, Jens Baumgart <jens.baumgart@sap.com>
- * Copyright (C) 2010, Stefan Lay <stefan.lay@sap.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.op;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.jobs.ISchedulingRule;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.AdaptableFileTreeIterator;
-import org.eclipse.egit.core.CoreText;
-import org.eclipse.egit.core.internal.job.RuleUtil;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.jgit.api.AddCommand;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.api.errors.GitAPIException;
-import org.eclipse.jgit.lib.Repository;
-
-/**
- */
-public class AddToIndexOperation implements IEGitOperation {
-	private final Collection<? extends IResource> rsrcList;
-
-	/**
-	 * Create a new operation to add files to the Git index
-	 *
-	 * @param rsrcs
-	 *            collection of {@link IResource}s which should be added to the
-	 *            relevant Git repositories.
-	 */
-	public AddToIndexOperation(final Collection<? extends IResource> rsrcs) {
-		rsrcList = rsrcs;
-	}
-
-	/**
-	 * Create a new operation to add files to the Git index
-	 *
-	 * @param resources
-	 *            array of {@link IResource}s which should be added to the
-	 *            relevant Git repositories.
-	 */
-	public AddToIndexOperation(IResource[] resources) {
-		rsrcList = Arrays.asList(resources);
-	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.egit.core.op.IEGitOperation#execute(org.eclipse.core.runtime.IProgressMonitor)
-	 */
-	public void execute(IProgressMonitor m) throws CoreException {
-		IProgressMonitor monitor;
-		if (m == null)
-			monitor = new NullProgressMonitor();
-		else
-			monitor = m;
-
-		Map<RepositoryMapping, AddCommand> addCommands = new HashMap<RepositoryMapping, AddCommand>();
-		try {
-			for (IResource obj : rsrcList) {
-				addToCommand(obj, addCommands);
-				monitor.worked(200);
-			}
-
-			for (AddCommand command : addCommands.values()) {
-				command.call();
-			}
-		} catch (RuntimeException e) {
-			throw new CoreException(Activator.error(CoreText.AddToIndexOperation_failed, e));
-		} catch (GitAPIException e) {
-			throw new CoreException(Activator.error(CoreText.AddToIndexOperation_failed, e));
-		} finally {
-			for (final RepositoryMapping rm : addCommands.keySet())
-				rm.fireRepositoryChanged();
-			monitor.done();
-		}
-	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.egit.core.op.IEGitOperation#getSchedulingRule()
-	 */
-	public ISchedulingRule getSchedulingRule() {
-		return RuleUtil.getRuleForRepositories(rsrcList.toArray(new IResource[rsrcList.size()]));
-	}
-
-	private void addToCommand(IResource resource, Map<RepositoryMapping, AddCommand> addCommands) {
-		IProject project = resource.getProject();
-		RepositoryMapping map = RepositoryMapping.getMapping(project);
-		AddCommand command = addCommands.get(map);
-		if (command == null) {
-			Repository repo = map.getRepository();
-			Git git = new Git(repo);
-			AdaptableFileTreeIterator it = new AdaptableFileTreeIterator(repo,
-					resource.getWorkspace().getRoot());
-			command = git.add().setWorkingTreeIterator(it);
-			addCommands.put(map, command);
-		}
-		String filepattern = map.getRepoRelativePath(resource);
-		if ("".equals(filepattern)) //$NON-NLS-1$
-			filepattern = "."; //$NON-NLS-1$
-		command.addFilepattern(filepattern);
-	}
-
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/AssumeUnchangedOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/AssumeUnchangedOperation.java
deleted file mode 100644
index ea502f3..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/AssumeUnchangedOperation.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2007, Robin Rosenberg <robin.rosenberg@dewire.com>
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * Copyright (C) 2008, Google Inc.
- * Copyright (C) 2010, Matthias Sohn <matthias.sohn@sap.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.op;
-
-import java.io.IOException;
-import java.util.Collection;
-import java.util.IdentityHashMap;
-import java.util.Map;
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.jobs.ISchedulingRule;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.CoreText;
-import org.eclipse.egit.core.internal.job.RuleUtil;
-import org.eclipse.egit.core.project.GitProjectData;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.jgit.dircache.DirCache;
-import org.eclipse.jgit.dircache.DirCacheEntry;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.osgi.util.NLS;
-
-/**
- * Tell JGit to ignore changes in selected files
- */
-public class AssumeUnchangedOperation implements IEGitOperation {
-	private final Collection<? extends IResource> rsrcList;
-
-	private final IdentityHashMap<Repository, DirCache> caches;
-
-	private final IdentityHashMap<RepositoryMapping, Object> mappings;
-
-	private boolean assumeUnchanged;
-
-	/**
-	 * Create a new operation to ignore changes in tracked files
-	 *
-	 * @param rsrcs
-	 *            collection of {@link IResource}s which should be ignored when
-	 *            looking for changes or committing.
-	 * @param assumeUnchanged
-	 *            {@code true} to set the assume-valid flag in the git index
-	 *            entry, {@code false} to unset the assume-valid flag in the git
-	 *            index entry
-	 */
-	public AssumeUnchangedOperation(
-			final Collection<? extends IResource> rsrcs, boolean assumeUnchanged) {
-		rsrcList = rsrcs;
-		caches = new IdentityHashMap<Repository, DirCache>();
-		mappings = new IdentityHashMap<RepositoryMapping, Object>();
-		this.assumeUnchanged = assumeUnchanged;
-	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.egit.core.op.IEGitOperation#execute(org.eclipse.core.runtime.IProgressMonitor)
-	 */
-	public void execute(IProgressMonitor m) throws CoreException {
-		IProgressMonitor monitor;
-		if (m == null)
-			monitor = new NullProgressMonitor();
-		else
-			monitor = m;
-
-		caches.clear();
-		mappings.clear();
-
-		monitor.beginTask(CoreText.AssumeUnchangedOperation_adding,
-				rsrcList.size() * 200);
-		try {
-			for (IResource resource : rsrcList) {
-				assumeValid(resource);
-				monitor.worked(200);
-			}
-
-			for (Map.Entry<Repository, DirCache> e : caches.entrySet()) {
-				final Repository db = e.getKey();
-				final DirCache editor = e.getValue();
-				monitor.setTaskName(NLS.bind(
-						CoreText.AssumeUnchangedOperation_writingIndex, db
-								.getDirectory()));
-				editor.write();
-				editor.commit();
-			}
-		} catch (RuntimeException e) {
-			throw new CoreException(Activator.error(CoreText.UntrackOperation_failed, e));
-		} catch (IOException e) {
-			throw new CoreException(Activator.error(CoreText.UntrackOperation_failed, e));
-		} finally {
-			for (final RepositoryMapping rm : mappings.keySet())
-				rm.fireRepositoryChanged();
-			for (DirCache cache:caches.values())
-				cache.unlock();
-			caches.clear();
-			mappings.clear();
-			monitor.done();
-		}
-	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.egit.core.op.IEGitOperation#getSchedulingRule()
-	 */
-	public ISchedulingRule getSchedulingRule() {
-		return RuleUtil.getRuleForRepositories(rsrcList.toArray(new IResource[rsrcList.size()]));
-	}
-
-	private void assumeValid(final IResource resource) throws CoreException {
-		final IProject proj = resource.getProject();
-		final GitProjectData pd = GitProjectData.get(proj);
-		if (pd == null)
-			return;
-		final RepositoryMapping rm = pd.getRepositoryMapping(resource);
-		if (rm == null)
-			return;
-		final Repository db = rm.getRepository();
-
-		DirCache cache = caches.get(db);
-		if (cache == null) {
-			try {
-				cache = db.lockDirCache();
-			} catch (IOException err) {
-				throw new CoreException(Activator.error(CoreText.UntrackOperation_failed, err));
-			}
-			caches.put(db, cache);
-			mappings.put(rm, rm);
-		}
-
-		final String path = rm.getRepoRelativePath(resource);
-		if (resource instanceof IContainer) {
-			for (final DirCacheEntry ent : cache.getEntriesWithin(path))
-				ent.setAssumeValid(assumeUnchanged);
-		} else {
-			final DirCacheEntry ent = cache.getEntry(path);
-			if (ent != null)
-				ent.setAssumeValid(assumeUnchanged);
-		}
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/BaseOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/BaseOperation.java
deleted file mode 100644
index 28f9094..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/BaseOperation.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/******************************************************************************
- *  Copyright (c) 2012 GitHub Inc.
- *  All rights reserved. This program and the accompanying materials
- *  are made available under the terms of the Eclipse Public License v1.0
- *  which accompanies this distribution, and is available at
- *  http://www.eclipse.org/legal/epl-v10.html
- *
- *  Contributors:
- *    Kevin Sawicki (GitHub Inc.) - initial API and implementation
- *****************************************************************************/
-package org.eclipse.egit.core.op;
-
-import java.util.ArrayList;
-import java.util.Collection;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.jgit.lib.Repository;
-
-/**
- * Base operation that supports adding pre/post tasks
- */
-abstract class BaseOperation implements IEGitOperation {
-
-	protected final Repository repository;
-
-	protected Collection<PreExecuteTask> preTasks;
-
-	protected Collection<PostExecuteTask> postTasks;
-
-	BaseOperation(final Repository repository) {
-		this.repository = repository;
-	}
-
-	/**
-	 * Invoke all pre-execute tasks
-	 *
-	 * @param monitor
-	 * @throws CoreException
-	 */
-	protected void preExecute(IProgressMonitor monitor) throws CoreException {
-		synchronized (this) {
-			if (preTasks != null)
-				for (PreExecuteTask task : preTasks)
-					task.preExecute(repository, monitor);
-		}
-	}
-
-	/**
-	 * Invoke all post-execute tasks
-	 *
-	 * @param monitor
-	 * @throws CoreException
-	 */
-	protected void postExecute(IProgressMonitor monitor) throws CoreException {
-		synchronized (this) {
-			if (postTasks != null)
-				for (PostExecuteTask task : postTasks)
-					task.postExecute(repository, monitor);
-		}
-	}
-
-	/**
-	 * @param task
-	 *            to be performed before execution
-	 */
-	public synchronized void addPreExecuteTask(final PreExecuteTask task) {
-		if (preTasks == null)
-			preTasks = new ArrayList<PreExecuteTask>();
-		preTasks.add(task);
-	}
-
-	/**
-	 * @param task
-	 *            to be performed after execution
-	 */
-	public synchronized void addPostExecuteTask(PostExecuteTask task) {
-		if (postTasks == null)
-			postTasks = new ArrayList<PostExecuteTask>();
-		postTasks.add(task);
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/BranchOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/BranchOperation.java
deleted file mode 100644
index d60424e..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/BranchOperation.java
+++ /dev/null
@@ -1,266 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2007, Dave Watson <dwatson@mimvista.com>
- * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
- * Copyright (C) 2006, Shawn O. Pearce <spearce@spearce.org>
- * Copyright (C) 2010, Jens Baumgart <jens.baumgart@sap.com>
- * Copyright (C) 2010, 2011, Mathias Kinzler <mathias.kinzler@sap.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.op;
-
-import java.io.File;
-import java.io.IOException;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IProjectDescription;
-import org.eclipse.core.resources.IWorkspaceRunnable;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.core.runtime.jobs.ISchedulingRule;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.CoreText;
-import org.eclipse.egit.core.internal.util.ProjectUtil;
-import org.eclipse.jgit.api.CheckoutCommand;
-import org.eclipse.jgit.api.CheckoutResult;
-import org.eclipse.jgit.api.CheckoutResult.Status;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.api.errors.CheckoutConflictException;
-import org.eclipse.jgit.api.errors.GitAPIException;
-import org.eclipse.jgit.api.errors.JGitInternalException;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.lib.Repository;
-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.filter.AndTreeFilter;
-import org.eclipse.jgit.treewalk.filter.PathSuffixFilter;
-import org.eclipse.jgit.treewalk.filter.TreeFilter;
-import org.eclipse.jgit.util.FileUtils;
-import org.eclipse.osgi.util.NLS;
-
-/**
- * This class implements checkouts of a specific revision. A check is made that
- * this can be done without data loss.
- */
-public class BranchOperation extends BaseOperation {
-
-	private final String target;
-
-	private CheckoutResult result;
-
-	private boolean delete;
-
-	/**
-	 * Construct a {@link BranchOperation} object for a {@link Ref}.
-	 *
-	 * @param repository
-	 * @param target
-	 *            a {@link Ref} name or {@link RevCommit} id
-	 */
-	public BranchOperation(Repository repository, String target) {
-		this(repository, target, true);
-	}
-
-	/**
-	 * Construct a {@link BranchOperation} object for a {@link Ref}.
-	 *
-	 * @param repository
-	 * @param target
-	 *            a {@link Ref} name or {@link RevCommit} id
-	 * @param delete
-	 *            true to delete missing projects on new branch, false to close
-	 *            them
-	 */
-	public BranchOperation(Repository repository, String target, boolean delete) {
-		super(repository);
-		this.target = target;
-		this.delete = delete;
-	}
-
-	public void execute(IProgressMonitor m) throws CoreException {
-		IProgressMonitor monitor;
-		if (m == null)
-			monitor = new NullProgressMonitor();
-		else
-			monitor = m;
-
-		IWorkspaceRunnable action = new IWorkspaceRunnable() {
-
-			public void run(IProgressMonitor pm) throws CoreException {
-				preExecute(pm);
-
-				IProject[] missing = getMissingProjects(target, ProjectUtil
-						.getValidOpenProjects(repository));
-
-				pm.beginTask(NLS.bind(
-						CoreText.BranchOperation_performingBranch, target),
-						missing.length > 0 ? 3 : 2);
-
-				if (missing.length > 0) {
-					SubProgressMonitor closeMonitor = new SubProgressMonitor(
-							pm, 1);
-					closeMonitor.beginTask("", missing.length); //$NON-NLS-1$
-					for (IProject project : missing) {
-						closeMonitor.subTask(MessageFormat.format(
-								CoreText.BranchOperation_closingMissingProject,
-								project.getName()));
-						project.close(closeMonitor);
-					}
-					closeMonitor.done();
-				}
-
-				CheckoutCommand co = new Git(repository).checkout();
-				co.setName(target);
-
-				try {
-					co.call();
-				} catch (CheckoutConflictException e) {
-					return;
-				} catch (JGitInternalException e) {
-					throw new CoreException(Activator.error(e.getMessage(), e));
-				} catch (GitAPIException e) {
-					throw new CoreException(Activator.error(e.getMessage(), e));
-				} finally {
-					BranchOperation.this.result = co.getResult();
-				}
-				if (result.getStatus() == Status.NONDELETED)
-					retryDelete(result.getUndeletedList());
-				pm.worked(1);
-
-				List<String> pathsToHandle = new ArrayList<String>();
-				pathsToHandle.addAll(co.getResult().getModifiedList());
-				pathsToHandle.addAll(co.getResult().getRemovedList());
-				pathsToHandle.addAll(co.getResult().getConflictList());
-				IProject[] refreshProjects = ProjectUtil
-						.getProjectsContaining(repository, pathsToHandle);
-				ProjectUtil.refreshValidProjects(refreshProjects, delete,
-						new SubProgressMonitor(pm, 1));
-				pm.worked(1);
-
-				postExecute(pm);
-
-				pm.done();
-			}
-		};
-		// lock workspace to protect working tree changes
-		ResourcesPlugin.getWorkspace().run(action, monitor);
-	}
-
-	public ISchedulingRule getSchedulingRule() {
-		return ResourcesPlugin.getWorkspace().getRoot();
-	}
-
-	/**
-	 * @return the result of the operation
-	 */
-	public CheckoutResult getResult() {
-		return result;
-	}
-
-	void retryDelete(List<String> pathList) {
-		// try to delete, but for a short time only
-		long startTime = System.currentTimeMillis();
-		for (String path : pathList) {
-			if (System.currentTimeMillis() - startTime > 1000)
-				break;
-			File fileToDelete = new File(repository.getWorkTree(), path);
-			if (fileToDelete.exists())
-				try {
-					// Only files should be passed here, thus
-					// we ignore attempt to delete submodules when
-					// we switch to a branch without a submodule
-					if (!fileToDelete.isFile())
-						FileUtils.delete(fileToDelete, FileUtils.RETRY);
-				} catch (IOException e) {
-					// ignore here
-				}
-		}
-	}
-
-	/**
-	 * Compute the current projects that will be missing after the given branch
-	 * is checked out
-	 *
-	 * @param branch
-	 * @param currentProjects
-	 * @return non-null but possibly empty array of missing projects
-	 */
-	private IProject[] getMissingProjects(String branch,
-			IProject[] currentProjects) {
-		if (delete || currentProjects.length == 0)
-			return new IProject[0];
-
-		ObjectId targetTreeId;
-		ObjectId currentTreeId;
-		try {
-			targetTreeId = repository.resolve(branch + "^{tree}"); //$NON-NLS-1$
-			currentTreeId = repository.resolve(Constants.HEAD + "^{tree}"); //$NON-NLS-1$
-		} catch (IOException e) {
-			return new IProject[0];
-		}
-		if (targetTreeId == null || currentTreeId == null)
-			return new IProject[0];
-
-		Map<File, IProject> locations = new HashMap<File, IProject>();
-		for (IProject project : currentProjects) {
-			IPath location = project.getLocation();
-			if (location == null)
-				continue;
-			location = location
-					.append(IProjectDescription.DESCRIPTION_FILE_NAME);
-			locations.put(location.toFile(), project);
-		}
-
-		List<IProject> toBeClosed = new ArrayList<IProject>();
-		File root = repository.getWorkTree();
-		TreeWalk walk = new TreeWalk(repository);
-		try {
-			walk.addTree(targetTreeId);
-			walk.addTree(currentTreeId);
-			walk.addTree(new FileTreeIterator(repository));
-			walk.setRecursive(true);
-			walk.setFilter(AndTreeFilter.create(PathSuffixFilter
-					.create(IProjectDescription.DESCRIPTION_FILE_NAME),
-					TreeFilter.ANY_DIFF));
-			while (walk.next()) {
-				AbstractTreeIterator targetIter = walk.getTree(0,
-						AbstractTreeIterator.class);
-				if (targetIter != null)
-					continue;
-
-				AbstractTreeIterator currentIter = walk.getTree(1,
-						AbstractTreeIterator.class);
-				AbstractTreeIterator workingIter = walk.getTree(2,
-						AbstractTreeIterator.class);
-				if (currentIter == null || workingIter == null)
-					continue;
-
-				IProject project = locations.get(new File(root, walk
-						.getPathString()));
-				if (project != null)
-					toBeClosed.add(project);
-			}
-		} catch (IOException e) {
-			return new IProject[0];
-		} finally {
-			walk.release();
-		}
-		return toBeClosed.toArray(new IProject[toBeClosed.size()]);
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/CherryPickOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/CherryPickOperation.java
deleted file mode 100644
index 33579c5..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/CherryPickOperation.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/******************************************************************************
- *  Copyright (c) 2011 GitHub Inc.
- *  All rights reserved. This program and the accompanying materials
- *  are made available under the terms of the Eclipse Public License v1.0
- *  which accompanies this distribution, and is available at
- *  http://www.eclipse.org/legal/epl-v10.html
- *
- *  Contributors:
- *    Kevin Sawicki (GitHub Inc.) - initial API and implementation
- *****************************************************************************/
-package org.eclipse.egit.core.op;
-
-import java.text.MessageFormat;
-
-import org.eclipse.core.resources.IWorkspaceRunnable;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.core.runtime.jobs.ISchedulingRule;
-import org.eclipse.egit.core.CoreText;
-import org.eclipse.egit.core.internal.util.ProjectUtil;
-import org.eclipse.jgit.api.CherryPickCommand;
-import org.eclipse.jgit.api.CherryPickResult;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.api.errors.GitAPIException;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.team.core.TeamException;
-
-/**
- * Cherry pick operation
- */
-public class CherryPickOperation implements IEGitOperation {
-
-	private final Repository repo;
-
-	private final RevCommit commit;
-
-	private CherryPickResult result;
-
-	/**
-	 * Create cherry pick operation
-	 *
-	 * @param repository
-	 * @param commit
-	 */
-	public CherryPickOperation(Repository repository, RevCommit commit) {
-		this.repo = repository;
-		this.commit = commit;
-	}
-
-	/**
-	 * @return cherry pick result
-	 */
-	public CherryPickResult getResult() {
-		return result;
-	}
-
-	public void execute(IProgressMonitor m) throws CoreException {
-		IProgressMonitor monitor = m != null ? m : new NullProgressMonitor();
-		IWorkspaceRunnable action = new IWorkspaceRunnable() {
-
-			public void run(IProgressMonitor pm) throws CoreException {
-				pm.beginTask("", 2); //$NON-NLS-1$
-
-				pm.subTask(MessageFormat.format(
-						CoreText.CherryPickOperation_cherryPicking,
-						commit.name()));
-				CherryPickCommand command = new Git(repo).cherryPick().include(
-						commit.getId());
-				try {
-					result = command.call();
-				} catch (GitAPIException e) {
-					throw new TeamException(e.getLocalizedMessage(),
-							e.getCause());
-				}
-				pm.worked(1);
-
-				ProjectUtil.refreshValidProjects(
-						ProjectUtil.getValidOpenProjects(repo),
-						new SubProgressMonitor(pm, 1));
-
-				pm.done();
-			}
-		};
-		ResourcesPlugin.getWorkspace().run(action, monitor);
-	}
-
-	public ISchedulingRule getSchedulingRule() {
-		return ResourcesPlugin.getWorkspace().getRoot();
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/CloneOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/CloneOperation.java
deleted file mode 100644
index a6af63c..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/CloneOperation.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2007, Dave Watson <dwatson@mimvista.com>
- * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
- * Copyright (C) 2008, Roger C. Soares <rogersoares@intelinet.com.br>
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.op;
-
-import java.io.File;
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.egit.core.CoreText;
-import org.eclipse.egit.core.EclipseGitProgressTransformer;
-import org.eclipse.jgit.api.CloneCommand;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.transport.CredentialsProvider;
-import org.eclipse.jgit.transport.URIish;
-import org.eclipse.jgit.util.FileUtils;
-import org.eclipse.osgi.util.NLS;
-
-/**
- * Clones a repository from a remote location to a local location.
- */
-public class CloneOperation {
-	private final URIish uri;
-
-	private final boolean allSelected;
-
-	private boolean cloneSubmodules;
-
-	private final Collection<Ref> selectedBranches;
-
-	private final File workdir;
-
-	private final File gitdir;
-
-	private final String refName;
-
-	private final String remoteName;
-
-	private final int timeout;
-
-	private CredentialsProvider credentialsProvider;
-
-	private List<PostCloneTask> postCloneTasks;
-
-	/**
-	 * Create a new clone operation.
-	 *
-	 * @param uri
-	 *            remote we should fetch from.
-	 * @param allSelected
-	 *            true when all branches have to be fetched (indicates wildcard
-	 *            in created fetch refspec), false otherwise.
-	 * @param selectedBranches
-	 *            collection of branches to fetch. Ignored when allSelected is
-	 *            true.
-	 * @param workdir
-	 *            working directory to clone to. The directory may or may not
-	 *            already exist.
-	 * @param refName
-	 *            full name of ref to be checked out after clone, e.g.
-	 *            refs/heads/master, or null for no checkout
-	 * @param remoteName
-	 *            name of created remote config as source remote (typically
-	 *            named "origin").
-	 * @param timeout
-	 *            timeout in seconds
-	 */
-	public CloneOperation(final URIish uri, final boolean allSelected,
-			final Collection<Ref> selectedBranches, final File workdir,
-			final String refName, final String remoteName, int timeout) {
-		this.uri = uri;
-		this.allSelected = allSelected;
-		this.selectedBranches = selectedBranches;
-		this.workdir = workdir;
-		this.gitdir = new File(workdir, Constants.DOT_GIT);
-		this.refName = refName;
-		this.remoteName = remoteName;
-		this.timeout = timeout;
-	}
-
-	/**
-	 * Sets a credentials provider
-	 * @param credentialsProvider
-	 */
-	public void setCredentialsProvider(CredentialsProvider credentialsProvider) {
-		this.credentialsProvider = credentialsProvider;
-	}
-
-	/**
-	 * @param cloneSubmodules
-	 *            true to initialize and update submodules
-	 */
-	public void setCloneSubmodules(boolean cloneSubmodules) {
-		this.cloneSubmodules = cloneSubmodules;
-	}
-
-	/**
-	 * @param pm
-	 *            the monitor to be used for reporting progress and responding
-	 *            to cancellation. The monitor is never <code>null</code>
-	 * @throws InvocationTargetException
-	 * @throws InterruptedException
-	 */
-	public void run(final IProgressMonitor pm)
-			throws InvocationTargetException, InterruptedException {
-		final IProgressMonitor monitor;
-		if (pm == null)
-			monitor = new NullProgressMonitor();
-		else
-			monitor = pm;
-
-		EclipseGitProgressTransformer gitMonitor = new EclipseGitProgressTransformer(
-				monitor);
-		Repository repository = null;
-		try {
-			monitor.beginTask(NLS.bind(CoreText.CloneOperation_title, uri),
-					5000);
-			CloneCommand cloneRepository = Git.cloneRepository();
-			cloneRepository.setCredentialsProvider(credentialsProvider);
-			if (refName != null)
-				cloneRepository.setBranch(refName);
-			else
-				cloneRepository.setNoCheckout(true);
-			cloneRepository.setDirectory(workdir);
-			cloneRepository.setProgressMonitor(gitMonitor);
-			cloneRepository.setRemote(remoteName);
-			cloneRepository.setURI(uri.toString());
-			cloneRepository.setTimeout(timeout);
-			cloneRepository.setCloneAllBranches(allSelected);
-			cloneRepository.setCloneSubmodules(cloneSubmodules);
-			if (selectedBranches != null) {
-				List<String> branches = new ArrayList<String>();
-				for (Ref branch : selectedBranches)
-					branches.add(branch.getName());
-				cloneRepository.setBranchesToClone(branches);
-			}
-			Git git = cloneRepository.call();
-			repository = git.getRepository();
-			synchronized (this) {
-				if (postCloneTasks != null)
-					for (PostCloneTask task : postCloneTasks)
-						task.execute(git.getRepository(), monitor);
-			}
-		} catch (final Exception e) {
-			try {
-				if (repository != null)
-					repository.close();
-				FileUtils.delete(workdir, FileUtils.RECURSIVE);
-			} catch (IOException ioe) {
-				throw new InvocationTargetException(e, NLS.bind(
-						CoreText.CloneOperation_failed_cleanup,
-						ioe.getLocalizedMessage()));
-			}
-			if (monitor.isCanceled())
-				throw new InterruptedException();
-			else
-				throw new InvocationTargetException(e);
-		} finally {
-			monitor.done();
-			if (repository != null)
-				repository.close();
-		}
-	}
-
-	/**
-	 * @return The git directory which will contain the repository
-	 */
-	public File getGitDir() {
-		return gitdir;
-	}
-
-	/**
-	 * @param task to be performed after clone
-	 */
-	public synchronized void addPostCloneTask(PostCloneTask task) {
-		if (postCloneTasks == null)
-			postCloneTasks = new ArrayList<PostCloneTask>();
-		postCloneTasks.add(task);
-	}
-
-	/**
-	 * A task which can be added to be performed after clone
-	 */
-	public interface PostCloneTask  {
-
-		/**
-		 * Executes the task
-		 * @param repository the cloned git repository
-		 *
-		 * @param monitor
-		 *            a progress monitor, or <code>null</code> if progress reporting
-		 *            and cancellation are not desired
-		 * @throws CoreException
-		 */
-		void execute(Repository repository, IProgressMonitor monitor) throws CoreException;
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/CommitOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/CommitOperation.java
deleted file mode 100644
index 5ff3864..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/CommitOperation.java
+++ /dev/null
@@ -1,320 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010-2012, SAP AG and others.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *    Stefan Lay (SAP AG) - initial implementation
- *    Jens Baumgart (SAP AG)
- *    Robin Stocker (independent)
- *******************************************************************************/
-package org.eclipse.egit.core.op;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.TimeZone;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IWorkspaceRunnable;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.jobs.ISchedulingRule;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.CoreText;
-import org.eclipse.egit.core.RepositoryUtil;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.jgit.api.AddCommand;
-import org.eclipse.jgit.api.CommitCommand;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.api.errors.GitAPIException;
-import org.eclipse.jgit.api.errors.JGitInternalException;
-import org.eclipse.jgit.lib.PersonIdent;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.jgit.util.RawParseUtils;
-import org.eclipse.osgi.util.NLS;
-import org.eclipse.team.core.TeamException;
-
-/**
- * This class implements the commit of a list of files.
- */
-public class CommitOperation implements IEGitOperation {
-
-	Collection<String> commitFileList;
-
-	private boolean commitWorkingDirChanges = false;
-
-	private String author;
-
-	private String committer;
-
-	private String message;
-
-	private boolean amending = false;
-
-	private boolean commitAll = false;
-
-	private Repository repo;
-
-	Collection<String> notTracked;
-
-	private boolean createChangeId;
-
-	private boolean commitIndex;
-
-	RevCommit commit = null;
-
-	/**
-	 * @param filesToCommit
-	 *            a list of files which will be included in the commit
-	 * @param notTracked
-	 *            a list of all untracked files
-	 * @param author
-	 *            the author of the commit
-	 * @param committer
-	 *            the committer of the commit
-	 * @param message
-	 *            the commit message
-	 * @throws CoreException
-	 */
-	public CommitOperation(IFile[] filesToCommit, Collection<IFile> notTracked,
-			String author, String committer, String message) throws CoreException {
-		this.author = author;
-		this.committer = committer;
-		this.message = message;
-		if (filesToCommit != null && filesToCommit.length > 0)
-			setRepository(filesToCommit[0]);
-		if (filesToCommit != null)
-			commitFileList = buildFileList(Arrays.asList(filesToCommit));
-		if (notTracked != null)
-			this.notTracked = buildFileList(notTracked);
-	}
-
-	/**
-	 * @param repository
-	 * @param filesToCommit
-	 *            a list of files which will be included in the commit
-	 * @param notTracked
-	 *            a list of all untracked files
-	 * @param author
-	 *            the author of the commit
-	 * @param committer
-	 *            the committer of the commit
-	 * @param message
-	 *            the commit message
-	 * @throws CoreException
-	 */
-	public CommitOperation(Repository repository, Collection<String> filesToCommit, Collection<String> notTracked,
-			String author, String committer, String message) throws CoreException {
-		this.repo = repository;
-		this.author = author;
-		this.committer = committer;
-		this.message = message;
-		if (filesToCommit != null)
-			commitFileList = new HashSet<String>(filesToCommit);
-		if (notTracked != null)
-			this.notTracked = new HashSet<String>(notTracked);
-	}
-
-	/**
-	 * Constructs a CommitOperation that commits the index
-	 * @param repository
-	 * @param author
-	 * @param committer
-	 * @param message
-	 * @throws CoreException
-	 */
-	public CommitOperation(Repository repository, String author, String committer,
-			String message) throws CoreException {
-		this.repo = repository;
-		this.author = author;
-		this.committer = committer;
-		this.message = message;
-		this.commitIndex = true;
-	}
-
-
-	private void setRepository(IFile file) throws CoreException {
-		RepositoryMapping mapping = RepositoryMapping.getMapping(file);
-		if (mapping == null)
-			throw new CoreException(Activator.error(NLS.bind(
-					CoreText.CommitOperation_couldNotFindRepositoryMapping,
-					file), null));
-		repo = mapping.getRepository();
-	}
-
-	/**
-	 * @param repository
-	 */
-	public void setRepository(Repository repository) {
-		repo = repository;
-	}
-
-	private Collection<String> buildFileList(Collection<IFile> files) throws CoreException {
-		Collection<String> result = new HashSet<String>();
-		for (IFile file : files) {
-			RepositoryMapping mapping = RepositoryMapping.getMapping(file);
-			if (mapping == null)
-				throw new CoreException(Activator.error(NLS.bind(CoreText.CommitOperation_couldNotFindRepositoryMapping, file), null));
-			String repoRelativePath = mapping.getRepoRelativePath(file);
-			result.add(repoRelativePath);
-		}
-		return result;
-	}
-
-	public void execute(IProgressMonitor m) throws CoreException {
-		IProgressMonitor monitor;
-		if (m == null)
-			monitor = new NullProgressMonitor();
-		else
-			monitor = m;
-		IWorkspaceRunnable action = new IWorkspaceRunnable() {
-
-			public void run(IProgressMonitor actMonitor) throws CoreException {
-				if (commitAll)
-					commitAll();
-				else if (amending || commitFileList != null
-						&& commitFileList.size() > 0 || commitIndex) {
-					actMonitor.beginTask(
-							CoreText.CommitOperation_PerformingCommit,
-							20);
-					actMonitor.setTaskName(CoreText.CommitOperation_PerformingCommit);
-					addUntracked();
-					commit();
-					actMonitor.worked(10);
-				} else if (commitWorkingDirChanges) {
-					// TODO commit -a
-				} else {
-					// TODO commit
-				}
-			}
-
-		};
-		ResourcesPlugin.getWorkspace().run(action, monitor);
-	}
-
-	private void addUntracked() throws CoreException {
-		if (notTracked == null || notTracked.size() == 0)
-			return;
-		AddCommand addCommand = new Git(repo).add();
-		boolean fileAdded = false;
-		for (String path : notTracked)
-			if (commitFileList.contains(path)) {
-				addCommand.addFilepattern(path);
-				fileAdded = true;
-			}
-		if (fileAdded)
-			try {
-				addCommand.call();
-			} catch (Exception e) {
-				throw new CoreException(Activator.error(e.getMessage(), e));
-			}
-	}
-
-	public ISchedulingRule getSchedulingRule() {
-		return ResourcesPlugin.getWorkspace().getRoot();
-	}
-
-	private void commit() throws TeamException {
-		Git git = new Git(repo);
-		try {
-			CommitCommand commitCommand = git.commit();
-			setAuthorAndCommitter(commitCommand);
-			commitCommand.setAmend(amending)
-					.setMessage(message)
-					.setInsertChangeId(createChangeId);
-			if (!commitIndex)
-				for(String path:commitFileList)
-					commitCommand.setOnly(path);
-			commit = commitCommand.call();
-		} catch (Exception e) {
-			throw new TeamException(
-					CoreText.MergeOperation_InternalError, e);
-		}
-	}
-
-	/**
-	 *
-	 * @param amending
-	 */
-	public void setAmending(boolean amending) {
-		this.amending = amending;
-	}
-
-	/**
-	 *
-	 * @param commitAll
-	 */
-	public void setCommitAll(boolean commitAll) {
-		this.commitAll = commitAll;
-	}
-
-	/**
-	 * @param createChangeId
-	 *            <code>true</code> if a Change-Id should be inserted
-	 */
-	public void setComputeChangeId(boolean createChangeId) {
-		this.createChangeId = createChangeId;
-	}
-
-	/**
-	 * @return the newly created commit if committing was successful, null otherwise.
-	 */
-	public RevCommit getCommit() {
-		return commit;
-	}
-
-	// TODO: can the commit message be change by the user in case of a merge commit?
-	private void commitAll() throws TeamException {
-
-		Git git = new Git(repo);
-		try {
-			CommitCommand commitCommand = git.commit();
-			setAuthorAndCommitter(commitCommand);
-			commit = commitCommand.setAll(true).setMessage(message)
-					.setInsertChangeId(createChangeId).call();
-		} catch (JGitInternalException e) {
-			throw new TeamException(CoreText.MergeOperation_InternalError, e);
-		} catch (GitAPIException e) {
-			throw new TeamException(e.getLocalizedMessage(), e);
-		}
-	}
-
-	private void setAuthorAndCommitter(CommitCommand commitCommand) throws TeamException {
-		final Date commitDate = new Date();
-		final TimeZone timeZone = TimeZone.getDefault();
-
-		final PersonIdent enteredAuthor = RawParseUtils.parsePersonIdent(author);
-		final PersonIdent enteredCommitter = RawParseUtils.parsePersonIdent(committer);
-		if (enteredAuthor == null)
-			throw new TeamException(NLS.bind(
-					CoreText.CommitOperation_errorParsingPersonIdent, author));
-		if (enteredCommitter == null)
-			throw new TeamException(
-					NLS.bind(CoreText.CommitOperation_errorParsingPersonIdent,
-							committer));
-
-		PersonIdent authorIdent = new PersonIdent(enteredAuthor, commitDate, timeZone);
-		final PersonIdent committerIdent = new PersonIdent(enteredCommitter, commitDate, timeZone);
-
-		if (amending) {
-			RepositoryUtil repoUtil = Activator.getDefault().getRepositoryUtil();
-			RevCommit headCommit = repoUtil.parseHeadCommit(repo);
-			if (headCommit != null) {
-				final PersonIdent headAuthor = headCommit.getAuthorIdent();
-				authorIdent = new PersonIdent(enteredAuthor,
-						headAuthor.getWhen(), headAuthor.getTimeZone());
-			}
-		}
-
-		commitCommand.setAuthor(authorIdent);
-		commitCommand.setCommitter(committerIdent);
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/ConfigureFetchAfterCloneTask.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/ConfigureFetchAfterCloneTask.java
deleted file mode 100644
index 44f6af0..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/ConfigureFetchAfterCloneTask.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2011-2012, Stefan Lay <stefan.lay@sap.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.op;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.CoreText;
-import org.eclipse.egit.core.op.CloneOperation.PostCloneTask;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.transport.RefSpec;
-import org.eclipse.jgit.transport.RemoteConfig;
-import org.eclipse.osgi.util.NLS;
-
-/**
- * Adds a fetch specification of the cloned repository and performs a fetch
- */
-public class ConfigureFetchAfterCloneTask implements PostCloneTask {
-
-	private String fetchRefSpec;
-
-	private final String remoteName;
-
-	/**
-	 * @param remoteName name of the remote in the git config file
-	 * @param fetchRefSpec the fetch ref spec which will be added
-	 */
-	public ConfigureFetchAfterCloneTask(String remoteName, String fetchRefSpec) {
-		this.remoteName = remoteName;
-		this.fetchRefSpec = fetchRefSpec;
-	}
-
-	/**
-	 * @param repository the cloned repository
-	 * @param monitor
-	 * @throws CoreException
-	 */
-	public void execute(Repository repository, IProgressMonitor monitor)
-			throws CoreException {
-		try {
-			RemoteConfig configToUse = new RemoteConfig(
-					repository.getConfig(), remoteName);
-			if (fetchRefSpec != null)
-				configToUse.addFetchRefSpec(new RefSpec(fetchRefSpec));
-			configToUse.update(repository.getConfig());
-			repository.getConfig().save();
-			Git git = new Git(repository);
-			try {
-				git.fetch().setRemote(remoteName).call();
-			} catch (Exception e) {
-				Activator.logError(NLS.bind(CoreText.ConfigureFetchAfterCloneTask_couldNotFetch, fetchRefSpec), e);
-			}
-		} catch (Exception e) {
-			throw new CoreException(Activator.error(e.getMessage(), e));
-		}
-
-	}
-
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/ConfigurePushAfterCloneTask.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/ConfigurePushAfterCloneTask.java
deleted file mode 100644
index 3e1f16c..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/ConfigurePushAfterCloneTask.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2011, Stefan Lay <stefan.lay@sap.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.op;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.op.CloneOperation.PostCloneTask;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.transport.RefSpec;
-import org.eclipse.jgit.transport.RemoteConfig;
-import org.eclipse.jgit.transport.URIish;
-
-/**
- * Configures the push specification of the cloned repository
- */
-public class ConfigurePushAfterCloneTask implements PostCloneTask {
-
-	private String pushRefSpec;
-
-	private URIish pushURI;
-
-	private final String remoteName;
-
-	/**
-	 * @param remoteName
-	 * @param pushRefSpec
-	 * @param pushURI
-	 */
-	public ConfigurePushAfterCloneTask(String remoteName, String pushRefSpec, URIish pushURI) {
-		this.remoteName = remoteName;
-		this.pushRefSpec = pushRefSpec;
-		this.pushURI = pushURI;
-	}
-
-	/**
-	 * @param repository
-	 * @param monitor
-	 * @throws CoreException
-	 */
-	public void execute(Repository repository, IProgressMonitor monitor)
-			throws CoreException {
-		try {
-			RemoteConfig configToUse = new RemoteConfig(
-					repository.getConfig(), remoteName);
-			if (pushRefSpec != null)
-				configToUse.addPushRefSpec(new RefSpec(pushRefSpec));
-			if (pushURI != null)
-				configToUse.addPushURI(pushURI);
-			configToUse.update(repository.getConfig());
-			repository.getConfig().save();
-		} catch (Exception e) {
-			throw new CoreException(Activator.error(e.getMessage(), e));
-		}
-
-	}
-
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/ConnectProviderOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/ConnectProviderOperation.java
deleted file mode 100644
index 4370e6c..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/ConnectProviderOperation.java
+++ /dev/null
@@ -1,220 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * Copyright (C) 2008, Google Inc.
- * Copyright (C) 2009, Mykola Nikishov <mn@mn.com.ua>
- * Copyright (C) 2013, Matthias Sohn <matthias.sohn@sap.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.op;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.MultiStatus;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.core.runtime.jobs.ISchedulingRule;
-import org.eclipse.core.runtime.jobs.MultiRule;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.CoreText;
-import org.eclipse.egit.core.GitProvider;
-import org.eclipse.egit.core.internal.trace.GitTraceLocation;
-import org.eclipse.egit.core.project.GitProjectData;
-import org.eclipse.egit.core.project.RepositoryFinder;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.osgi.util.NLS;
-import org.eclipse.team.core.RepositoryProvider;
-
-/**
- * Connects Eclipse to an existing Git repository
- */
-public class ConnectProviderOperation implements IEGitOperation {
-	private final Map<IProject, File> projects = new HashMap<IProject, File>();
-
-	/**
-	 * Create a new connection operation to execute within the workspace.
-	 * <p>
-	 * Uses <code>.git</code> as a default relative path to repository.
-	 * @see #ConnectProviderOperation(IProject, File)
-	 *
-	 * @param proj
-	 *            the project to connect to the Git team provider.
-	 */
-	public ConnectProviderOperation(final IProject proj) {
-		this(proj, proj.getLocation().append(Constants.DOT_GIT).toFile());
-	}
-
-	/**
-	 * Create a new connection operation to execute within the workspace.
-	 *
-	 * @param proj
-	 *            the project to connect to the Git team provider.
-	 * @param pathToRepo
-	 *            absolute path to the repository
-	 */
-	public ConnectProviderOperation(final IProject proj, File pathToRepo) {
-		this.projects.put(proj, pathToRepo);
-	}
-
-	/**
-	 * Create a new connection operation to execute within the workspace.
-	 *
-	 * @param projects
-	 *            the projects to connect to the Git team provider.
-	 */
-	public ConnectProviderOperation(final Map<IProject, File> projects) {
-		this.projects.putAll(projects);
-	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.egit.core.op.IEGitOperation#execute(org.eclipse.core.runtime.IProgressMonitor)
-	 */
-	public void execute(IProgressMonitor m) throws CoreException {
-		IProgressMonitor monitor;
-		if (m == null) {
-			monitor = new NullProgressMonitor();
-		} else {
-			monitor = m;
-		}
-
-		monitor.beginTask(CoreText.ConnectProviderOperation_connecting,
-				100 * projects.size());
-		try {
-
-			for (Iterator iterator = projects.keySet().iterator(); iterator.hasNext();) {
-				IProject project = (IProject) iterator.next();
-				monitor.setTaskName(NLS.bind(
-						CoreText.ConnectProviderOperation_ConnectingProject,
-						project.getName()));
-				// TODO is this the right location?
-				if (GitTraceLocation.CORE.isActive())
-					GitTraceLocation.getTrace().trace(
-							GitTraceLocation.CORE.getLocation(),
-							"Locating repository for " + project); //$NON-NLS-1$
-
-				Collection<RepositoryMapping> repos = new RepositoryFinder(
-						project).find(new SubProgressMonitor(monitor, 40));
-				File suggestedRepo = projects.get(project);
-				RepositoryMapping actualMapping= findActualRepository(repos, suggestedRepo);
-				if (actualMapping != null) {
-					GitProjectData projectData = new GitProjectData(project);
-					try {
-						projectData.setRepositoryMappings(Arrays.asList(actualMapping));
-						projectData.store();
-						GitProjectData.add(project, projectData);
-					} catch (CoreException ce) {
-						try {
-							GitProjectData.delete(project);
-						} catch (IOException e) {
-							MultiStatus status = new MultiStatus(
-									Activator.getPluginId(), IStatus.ERROR,
-									e.getMessage(), e);
-							status.add(new Status(IStatus.ERROR, Activator
-									.getPluginId(), ce.getMessage(), ce));
-							throw new CoreException(status);
-						}
-						throw ce;
-					} catch (RuntimeException ce) {
-						try {
-							GitProjectData.delete(project);
-						} catch (IOException e) {
-							MultiStatus status = new MultiStatus(
-									Activator.getPluginId(), IStatus.ERROR,
-									e.getMessage(), e);
-							status.add(new Status(IStatus.ERROR, Activator
-									.getPluginId(), ce.getMessage(), ce));
-							throw new CoreException(status);
-					}
-						throw ce;
-					}
-					RepositoryProvider
-							.map(project, GitProvider.class.getName());
-					autoIgnoreDerivedResources(project, monitor);
-					project.refreshLocal(IResource.DEPTH_INFINITE,
-							new SubProgressMonitor(monitor, 50));
-					monitor.worked(10);
-				} else {
-					// TODO is this the right location?
-					if (GitTraceLocation.CORE.isActive())
-						GitTraceLocation.getTrace().trace(
-								GitTraceLocation.CORE.getLocation(),
-								"Attempted to share project without repository ignored :" //$NON-NLS-1$
-										+ project);
-					monitor.worked(60);
-				}
-			}
-		} finally {
-			monitor.done();
-		}
-	}
-
-	private void autoIgnoreDerivedResources(IProject project,
-			IProgressMonitor monitor) throws CoreException {
-		List<IPath> paths = findDerivedResources(project);
-		if (paths.size() > 0) {
-			IgnoreOperation ignoreOp = new IgnoreOperation(paths);
-			IProgressMonitor subMonitor = new SubProgressMonitor(monitor, 1);
-			ignoreOp.execute(subMonitor);
-		}
-	}
-
-	private List<IPath> findDerivedResources(IContainer c)
-			throws CoreException {
-		List<IPath> derived = new ArrayList<IPath>();
-		IResource[] members = c.members(IContainer.INCLUDE_HIDDEN);
-		for (IResource r : members) {
-			if (r.isDerived())
-				derived.add(r.getLocation());
-			else if (r instanceof IContainer)
-				derived.addAll(findDerivedResources((IContainer) r));
-		}
-		return derived;
-	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.egit.core.op.IEGitOperation#getSchedulingRule()
-	 */
-	public ISchedulingRule getSchedulingRule() {
-		Set<IProject> projectSet = projects.keySet();
-		return new MultiRule(projectSet.toArray(new IProject[projectSet.size()]));
-	}
-
-	/**
-	 * @param repos
-	 *         available repositories
-	 * @param suggestedRepo
-	 *         relative path to git repository
-	 * @return a repository mapping which corresponds to a suggested repository
-	 *         location, <code>null</code> otherwise
-	 */
-	private RepositoryMapping findActualRepository(
-			Collection<RepositoryMapping> repos, File suggestedRepo) {
-		for (RepositoryMapping rm : repos) {
-			if (rm.getGitDirAbsolutePath().equals(Path.fromOSString(suggestedRepo.getPath())))
-				return rm;
-		}
-		return null;
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/CreateLocalBranchOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/CreateLocalBranchOperation.java
deleted file mode 100644
index 112e14b..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/CreateLocalBranchOperation.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2010, Mathias Kinzler <mathias.kinzler@sap.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.op;
-
-import java.io.IOException;
-
-import org.eclipse.core.resources.IWorkspaceRunnable;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.jobs.ISchedulingRule;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.CoreText;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.api.CreateBranchCommand.SetupUpstreamMode;
-import org.eclipse.jgit.lib.ConfigConstants;
-import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.lib.StoredConfig;
-import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.osgi.util.NLS;
-
-/**
- * This class implements creation of a local branch based on a commit or another
- * branch
- */
-public class CreateLocalBranchOperation implements IEGitOperation {
-	private final String name;
-
-	private final Repository repository;
-
-	private final Ref ref;
-
-	private final RevCommit commit;
-
-	private final UpstreamConfig upstreamConfig;
-
-	/**
-	 * @param repository
-	 * @param name
-	 *            the name for the new local branch (without prefix)
-	 * @param ref
-	 *            the branch or tag to base the new branch upon
-	 * @param config
-	 *            how to do the upstream configuration
-	 */
-	public CreateLocalBranchOperation(Repository repository, String name,
-			Ref ref, UpstreamConfig config) {
-		this.name = name;
-		this.repository = repository;
-		this.ref = ref;
-		this.commit = null;
-		this.upstreamConfig = config;
-	}
-
-	/**
-	 * @param repository
-	 * @param name
-	 *            the name for the new local branch (without prefix)
-	 * @param commit
-	 *            a commit to base the new branch upon
-	 */
-	public CreateLocalBranchOperation(Repository repository, String name,
-			RevCommit commit) {
-		this.name = name;
-		this.repository = repository;
-		this.ref = null;
-		this.commit = commit;
-		this.upstreamConfig = null;
-	}
-
-	public void execute(IProgressMonitor m) throws CoreException {
-		IProgressMonitor monitor;
-		if (m == null)
-			monitor = new NullProgressMonitor();
-		else
-			monitor = m;
-
-		IWorkspaceRunnable action = new IWorkspaceRunnable() {
-			public void run(IProgressMonitor actMonitor) throws CoreException {
-				String taskName = NLS
-						.bind(
-								CoreText.CreateLocalBranchOperation_CreatingBranchMessage,
-								name);
-				actMonitor.beginTask(taskName, 1);
-				Git git = new Git(repository);
-				try {
-					if (ref != null) {
-						SetupUpstreamMode mode;
-						if (upstreamConfig == UpstreamConfig.NONE)
-							mode = SetupUpstreamMode.NOTRACK;
-						else
-							mode = SetupUpstreamMode.SET_UPSTREAM;
-						git.branchCreate().setName(name).setStartPoint(
-								ref.getName()).setUpstreamMode(mode).call();
-					}
-					else
-						git.branchCreate().setName(name).setStartPoint(commit)
-								.setUpstreamMode(SetupUpstreamMode.NOTRACK)
-								.call();
-				} catch (Exception e) {
-					throw new CoreException(Activator.error(e.getMessage(), e));
-				}
-
-				if (UpstreamConfig.REBASE == upstreamConfig) {
-					// set "branch.<name>.rebase" to "true"
-					StoredConfig config = repository.getConfig();
-					config.setBoolean(ConfigConstants.CONFIG_BRANCH_SECTION,
-							name, ConfigConstants.CONFIG_KEY_REBASE, true);
-					try {
-						config.save();
-					} catch (IOException e) {
-						throw new CoreException(Activator.error(e.getMessage(),
-								e));
-					}
-				}
-				actMonitor.worked(1);
-				actMonitor.done();
-			}
-		};
-		// lock workspace to protect working tree changes
-		ResourcesPlugin.getWorkspace().run(action, monitor);
-	}
-
-	public ISchedulingRule getSchedulingRule() {
-		return ResourcesPlugin.getWorkspace().getRoot();
-	}
-
-	/**
-	 * Describes how to configure the upstream branch
-	 */
-	public static enum UpstreamConfig {
-		/** Rebase */
-		REBASE(),
-		/** Merge */
-		MERGE(),
-		/** No configuration */
-		NONE();
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/CreatePatchOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/CreatePatchOperation.java
deleted file mode 100644
index 6e96e4f..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/CreatePatchOperation.java
+++ /dev/null
@@ -1,468 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010, 2012 SAP AG and others.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *    Stefan Lay (SAP AG) - initial implementation
- *    Benjamin Muskalla (Tasktop Technologies) - extract into operation
- *    Tomasz Zarna (IBM Corporation) - bug 370332
- *    Daniel Megert <daniel_megert@ch.ibm.com> - Allow spaces in path
- *******************************************************************************/
-package org.eclipse.egit.core.op;
-
-import static org.eclipse.jgit.lib.Constants.encodeASCII;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.net.URI;
-import java.text.SimpleDateFormat;
-import java.util.List;
-import java.util.Locale;
-import java.util.Stack;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.eclipse.core.filesystem.URIUtil;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.Assert;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.core.runtime.jobs.ISchedulingRule;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.CoreText;
-import org.eclipse.egit.core.EclipseGitProgressTransformer;
-import org.eclipse.egit.core.internal.CompareCoreUtils;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.jgit.diff.DiffEntry;
-import org.eclipse.jgit.diff.DiffEntry.ChangeType;
-import org.eclipse.jgit.diff.DiffEntry.Side;
-import org.eclipse.jgit.diff.DiffFormatter;
-import org.eclipse.jgit.diff.RawText;
-import org.eclipse.jgit.dircache.DirCacheIterator;
-import org.eclipse.jgit.errors.CorruptObjectException;
-import org.eclipse.jgit.errors.MissingObjectException;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.jgit.treewalk.FileTreeIterator;
-import org.eclipse.jgit.treewalk.filter.TreeFilter;
-import org.eclipse.osgi.util.NLS;
-
-/**
- * Creates a patch for a specific commit
- */
-public class CreatePatchOperation implements IEGitOperation {
-
-	/**
-	 * Diff header format
-	 *
-	 */
-	public enum DiffHeaderFormat {
-		/**
-		 * No header
-		 */
-		NONE(CoreText.DiffHeaderFormat_None, false, null),
-
-		/**
-		 * Workspace patch
-		 */
-		WORKSPACE(CoreText.DiffHeaderFormat_Workspace, false, "### Eclipse Workspace Patch 1.0\n"), //$NON-NLS-1$
-
-		/**
-		 * Email header
-		 */
-		EMAIL(CoreText.DiffHeaderFormat_Email, true, "From ${sha1} ${date}\nFrom: ${author}\nDate: ${author date}\nSubject: [PATCH] ${title line}\n${full commit message}\n"), //$NON-NLS-1$
-
-		/**
-		 * Header designed to be as compact as possible
-		 */
-		ONELINE(CoreText.DiffHeaderFormat_Oneline, true, "${sha1} ${title line}\n"); //$NON-NLS-1$
-
-		private final String description;
-
-		private final boolean commitRequired;
-
-		private final String template;
-
-		private DiffHeaderFormat(final String d, final boolean c, final String t) {
-			description = d;
-			commitRequired = c;
-			template = t;
-		}
-
-		/**
-		 * @return if this format requires a commit.
-		 */
-		public boolean isCommitRequired() {
-			return commitRequired;
-		}
-
-		/**
-		 * @return the template
-		 */
-		public String getTemplate() {
-			return template;
-		}
-
-		/**
-		 * @return the description
-		 */
-		public String getDescription() {
-			return description;
-		}
-	}
-
-	enum DiffHeaderKeyword{
-		SHA1, AUTHOR_DATE, AUTHOR, DATE, TITLE_LINE, FULL_COMMIT_MESSAGE
-	}
-
-	/**
-	 * The default number of lines to use as context
-	 */
-	public static final int DEFAULT_CONTEXT_LINES = 3;
-
-	private final RevCommit commit;
-
-	private final Repository repository;
-
-	private DiffHeaderFormat headerFormat = DiffHeaderFormat.EMAIL;
-
-	// the encoding for the currently processed file
-	private String currentEncoding = null;
-
-	private String patchContent;
-
-	private int contextLines = DEFAULT_CONTEXT_LINES;
-
-	private TreeFilter pathFilter = null;
-
-	/**
-	 * Creates the new operation.
-	 *
-	 * @param repository
-	 * @param commit
-	 */
-	public CreatePatchOperation(Repository repository, RevCommit commit) {
-		if (repository == null)
-			throw new IllegalArgumentException(
-					CoreText.CreatePatchOperation_repoRequired);
-		this.repository = repository;
-		this.commit = commit;
-	}
-
-	public void execute(IProgressMonitor monitor) throws CoreException {
-		EclipseGitProgressTransformer gitMonitor;
-		if (monitor == null)
-			gitMonitor = new EclipseGitProgressTransformer(
-					new NullProgressMonitor());
-		else
-			gitMonitor = new EclipseGitProgressTransformer(monitor);
-
-		final StringBuilder sb = new StringBuilder();
-		final DiffFormatter diffFmt = new DiffFormatter(
-				new ByteArrayOutputStream() {
-
-					@Override
-					public synchronized void write(byte[] b, int off, int len) {
-						super.write(b, off, len);
-						if (currentEncoding == null)
-							sb.append(toString());
-						else
-							try {
-								sb.append(toString(currentEncoding));
-							} catch (UnsupportedEncodingException e) {
-								sb.append(toString());
-							}
-						reset();
-					}
-				}) {
-			private IProject project;
-
-			@Override
-			public void format(DiffEntry ent) throws IOException,
-					CorruptObjectException, MissingObjectException {
-				// for "workspace patches" add project header each time project changes
-				if (DiffHeaderFormat.WORKSPACE == headerFormat) {
-					IProject p = getProject(ent);
-					if (!p.equals(project)) {
-						project = p;
-						getOutputStream().write(
-								encodeASCII("#P " + project.getName() + "\n")); //$NON-NLS-1$ //$NON-NLS-2$
-					}
-				}
-				super.format(ent);
-			}
-		};
-
-		diffFmt.setProgressMonitor(gitMonitor);
-		diffFmt.setContext(contextLines);
-
-		if (headerFormat != null && headerFormat != DiffHeaderFormat.NONE)
-			writeGitPatchHeader(sb);
-
-		diffFmt.setRepository(repository);
-		diffFmt.setPathFilter(pathFilter);
-
-		try {
-			if (commit != null) {
-				RevCommit[] parents = commit.getParents();
-				if (parents.length > 1)
-					throw new IllegalStateException(
-							CoreText.CreatePatchOperation_cannotCreatePatchForMergeCommit);
-				if (parents.length == 0)
-					throw new IllegalStateException(
-							CoreText.CreatePatchOperation_cannotCreatePatchForFirstCommit);
-
-				List<DiffEntry> diffs = diffFmt.scan(parents[0].getId(),commit.getId());
-				for (DiffEntry ent : diffs) {
-					String path;
-					if (ChangeType.DELETE.equals(ent.getChangeType()))
-						path = ent.getOldPath();
-					else
-						path = ent.getNewPath();
-					currentEncoding = CompareCoreUtils.getResourceEncoding(repository, path);
-					diffFmt.format(ent);
-				}
-			} else
-				diffFmt.format(
-						new DirCacheIterator(repository.readDirCache()),
-						new FileTreeIterator(repository));
-		} catch (IOException e) {
-			Activator.logError(CoreText.CreatePatchOperation_patchFileCouldNotBeWritten, e);
-		}
-
-		if (DiffHeaderFormat.WORKSPACE == headerFormat)
-			updateWorkspacePatchPrefixes(sb, diffFmt);
-
-		// trim newline
-		if (sb.charAt(sb.length() - 1) == '\n')
-			sb.setLength(sb.length() - 1);
-
-		patchContent = sb.toString();
-	}
-
-	private IProject getProject(final DiffEntry ent) {
-		Side side = ent.getChangeType() == ChangeType.ADD ? Side.NEW : Side.OLD;
-		String path = ent.getPath(side);
-		return getProject(path);
-	}
-
-	private IProject getProject(String path) {
-		URI pathUri = repository.getWorkTree().toURI().resolve(URIUtil.toURI(path));
-		IFile[] files = ResourcesPlugin.getWorkspace().getRoot()
-				.findFilesForLocationURI(pathUri);
-		Assert.isLegal(files.length == 1, NLS.bind(CoreText.CreatePatchOperation_couldNotFindProject, path, repository));
-		return files[0].getProject();
-	}
-
-	/**
-	 * Retrieves the content of the requested patch
-	 *
-	 * @return the content of the patch
-	 */
-	public String getPatchContent() {
-		if (patchContent == null)
-			throw new IllegalStateException(
-					"#execute needs to be called before this method."); //$NON-NLS-1$
-		return patchContent;
-	}
-
-	private void writeGitPatchHeader(StringBuilder sb) {
-		String template = headerFormat.getTemplate();
-		String[] segments = template.split("\\$\\{"); //$NON-NLS-1$
-		Stack<String> evaluated = new Stack<String>();
-		evaluated.add(segments[0]);
-
-		for (int i = 1; i < segments.length; i++) {
-			String segment = segments[i];
-			String value = null;
-			int brace = segment.indexOf('}');
-			if (brace > 0) {
-				String keyword = segment.substring(0, brace);
-				keyword = keyword.toUpperCase().replaceAll(" ", "_"); //$NON-NLS-1$ //$NON-NLS-2$
-				value = processKeyword(commit, DiffHeaderKeyword.valueOf(keyword));
-			}
-
-			String trailingCharacters = segment.substring(brace + 1);
-			if (value != null) {
-				evaluated.add(value);
-				evaluated.add(trailingCharacters);
-			} else if (!evaluated.isEmpty())
-				evaluated.add(trailingCharacters);
-		}
-		StringBuffer buffer = new StringBuffer();
-		for (String string : evaluated)
-			buffer.append(string);
-
-		sb.append(buffer);
-	}
-
-	private static String processKeyword(RevCommit commit, DiffHeaderKeyword keyword) {
-		final SimpleDateFormat dtfmt = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z", Locale.US); //$NON-NLS-1$
-		switch (keyword) {
-		case SHA1:
-			return commit.getId().getName();
-		case AUTHOR:
-			return commit.getAuthorIdent().getName()
-					+ " <" + commit.getAuthorIdent().getEmailAddress() + ">"; //$NON-NLS-1$ //$NON-NLS-2$
-		case AUTHOR_DATE:
-			dtfmt.setTimeZone(commit.getAuthorIdent().getTimeZone());
-			return dtfmt.format(commit.getAuthorIdent().getWhen());
-		case DATE:
-			return dtfmt.format(Long.valueOf(System.currentTimeMillis()));
-		case TITLE_LINE:
-			return commit.getShortMessage();
-		case FULL_COMMIT_MESSAGE:
-			return commit.getFullMessage().substring(
-					commit.getShortMessage().length());
-		default:
-			return null;
-		}
-	}
-
-	/**
-	 * Updates prefixes to workspace paths
-	 *
-	 * @param sb
-	 * @param diffFmt
-	 */
-	public void updateWorkspacePatchPrefixes(StringBuilder sb, DiffFormatter diffFmt) {
-		RawText rt = new RawText(sb.toString().getBytes());
-
-		final String oldPrefix = diffFmt.getOldPrefix();
-		final String newPrefix = diffFmt.getNewPrefix();
-
-		StringBuilder newSb = new StringBuilder();
-		final Pattern diffPattern = Pattern
-				.compile("^diff --git (" + oldPrefix + "(.+)) (" + newPrefix + "(.+))$"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
-		final Pattern oldPattern = Pattern
-				.compile("^--- (" + oldPrefix + "(.+))$"); //$NON-NLS-1$ //$NON-NLS-2$
-		final Pattern newPattern = Pattern
-				.compile("^\\+\\+\\+ (" + newPrefix + "(.+))$"); //$NON-NLS-1$ //$NON-NLS-2$
-
-		int i = 0;
-		while (i < rt.size()) {
-			String line = rt.getString(i);
-
-			Matcher diffMatcher = diffPattern.matcher(line);
-			Matcher oldMatcher = oldPattern.matcher(line);
-			Matcher newMatcher = newPattern.matcher(line);
-			if (diffMatcher.find()) {
-				String group = diffMatcher.group(2); // old path
-				IProject project = getProject(group);
-				IPath newPath = computeWorkspacePath(new Path(group), project);
-				line = line.replaceAll(diffMatcher.group(1), newPath.toString());
-				group = diffMatcher.group(4); // new path
-				newPath = computeWorkspacePath(new Path(group), project);
-				line = line.replaceAll(diffMatcher.group(3), newPath.toString());
-			} else if (oldMatcher.find()) {
-				String group = oldMatcher.group(2);
-				IProject project = getProject(group);
-				IPath newPath = computeWorkspacePath(new Path(group), project);
-				line = line.replaceAll(oldMatcher.group(1), newPath.toString());
-			} else if (newMatcher.find()) {
-				String group = newMatcher.group(2);
-				IProject project = getProject(group);
-				IPath newPath = computeWorkspacePath(new Path(group), project);
-				line = line.replaceAll(newMatcher.group(1), newPath.toString());
-			}
-			newSb.append(line);
-
-			i++;
-			if (i < rt.size() || !rt.isMissingNewlineAtEnd())
-				newSb.append(rt.getLineDelimiter());
-		}
-		// reset sb to newSb
-		sb.setLength(0);
-		sb.append(newSb);
-	}
-
-	/**
-	 * Returns a workspace path
-	 *
-	 * @param path
-	 * @param project
-	 * @return path
-	 */
-	public static IPath computeWorkspacePath(final IPath path, final IProject project) {
-		RepositoryMapping rm = RepositoryMapping.getMapping(project);
-		String repoRelativePath = rm.getRepoRelativePath(project);
-		// the relative path cannot be determined, return unchanged
-		if (repoRelativePath == null)
-			return path;
-		// repository and project at the same level
-		if (repoRelativePath.equals("")) //$NON-NLS-1$
-			return path;
-		return path.removeFirstSegments(path.matchingFirstSegments(new Path(
-				repoRelativePath)));
-	}
-
-
-	/**
-	 * Change the format of diff header
-	 *
-	 * @param format header format
-	 */
-	public void setHeaderFormat(DiffHeaderFormat format) {
-		this.headerFormat = format;
-	}
-
-	/**
-	 * Change the number of lines of context to display.
-	 *
-	 * @param contextLines line count
-	 */
-	public void setContextLines(int contextLines) {
-		this.contextLines = contextLines;
-	}
-
-	/**
-	 * Suggests a file name for the patch given the commit.
-	 *
-	 * @param commit
-	 * @return a file name for a patch
-	 */
-	public static String suggestFileName(RevCommit commit) {
-		String name = commit.getShortMessage();
-
-		name = name.trim();
-		StringBuilder filteredBuilder = new StringBuilder();
-		char[] charArray = name.toCharArray();
-		for (char c : charArray) {
-			if(Character.isLetter(c) || Character.isDigit(c))
-				filteredBuilder.append(c);
-			if(Character.isWhitespace(c) || c == '/')
-				filteredBuilder.append("-"); //$NON-NLS-1$
-		}
-		name = filteredBuilder.toString();
-		if (name.length() > 52)
-			name = name.substring(0, 52);
-		while (name.endsWith(".")) //$NON-NLS-1$
-			name = name.substring(0, name.length() - 1);
-		name = name.concat(".patch"); //$NON-NLS-1$
-
-		return name;
-	}
-
-	public ISchedulingRule getSchedulingRule() {
-		return null;
-	}
-
-	/**
-	 * Set the filter to produce patch for specified paths only.
-	 *
-	 * @param pathFilter the filter
-	 */
-	public void setPathFilter(TreeFilter pathFilter) {
-		this.pathFilter = pathFilter;
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/DeleteBranchOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/DeleteBranchOperation.java
deleted file mode 100644
index 1b06d24..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/DeleteBranchOperation.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2010, Mathias Kinzler <mathias.kinzler@sap.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.op;
-
-import static java.util.Arrays.asList;
-
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-
-import org.eclipse.core.resources.IWorkspaceRunnable;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.jobs.ISchedulingRule;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.CoreText;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.api.errors.CannotDeleteCurrentBranchException;
-import org.eclipse.jgit.api.errors.GitAPIException;
-import org.eclipse.jgit.api.errors.JGitInternalException;
-import org.eclipse.jgit.api.errors.NotMergedException;
-import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.osgi.util.NLS;
-
-/**
- * This class implements deletion of a branch
- */
-public class DeleteBranchOperation implements IEGitOperation {
-	/** Operation was performed */
-	public final static int OK = 0;
-
-	/** Current branch can not be deleted */
-	public final static int REJECTED_CURRENT = 1;
-
-	/**
-	 * Branch to be deleted has not been fully merged; use force to delete
-	 * anyway
-	 */
-	public final static int REJECTED_UNMERGED = 2;
-
-	/** This operation was not executed yet */
-	public final static int NOT_TRIED = -1;
-
-	private int status = NOT_TRIED;
-
-	private final Repository repository;
-
-	private final Set<Ref> branches;
-
-	private final boolean force;
-
-	/**
-	 * @param repository
-	 * @param branch
-	 *            the branch to delete
-	 * @param force
-	 */
-	public DeleteBranchOperation(Repository repository, Ref branch,
-			boolean force) {
-		this(repository, new HashSet<Ref>(asList(branch)), force);
-	}
-
-	/**
-	 * @param repository
-	 * @param branches
-	 *            the list of branches to deleted
-	 * @param force
-	 */
-	public DeleteBranchOperation(Repository repository, Set<Ref> branches,
-			boolean force) {
-		this.repository = repository;
-		this.branches = branches;
-		this.force = force;
-	}
-
-	/**
-	 * @return one of {@link #OK}, {@link #REJECTED_CURRENT},
-	 *         {@link #REJECTED_UNMERGED}, {@link #NOT_TRIED}
-	 */
-	public int getStatus() {
-		return status;
-	}
-
-	public void execute(IProgressMonitor m) throws CoreException {
-		IProgressMonitor monitor;
-		if (m == null)
-			monitor = new NullProgressMonitor();
-		else
-			monitor = m;
-
-		IWorkspaceRunnable action = new IWorkspaceRunnable() {
-			public void run(IProgressMonitor actMonitor) throws CoreException {
-
-				String taskName;
-				if (branches.size() == 1)
-					taskName = NLS.bind(
-							CoreText.DeleteBranchOperation_TaskName, branches
-									.iterator().next().getName());
-				else {
-					StringBuilder names = new StringBuilder();
-					for (Iterator<Ref> it = branches.iterator(); it.hasNext(); ) {
-						Ref ref = it.next();
-						names.append(ref.getName());
-						if (it.hasNext())
-							names.append(", "); //$NON-NLS-1$
-					}
-					taskName = NLS.bind(
-							CoreText.DeleteBranchOperation_TaskName, names);
-				}
-				actMonitor.beginTask(taskName, branches.size());
-				for (Ref branch : branches) {
-					try {
-						new Git(repository).branchDelete().setBranchNames(
-								branch.getName()).setForce(force).call();
-						status = OK;
-					} catch (NotMergedException e) {
-						status = REJECTED_UNMERGED;
-						break;
-					} catch (CannotDeleteCurrentBranchException e) {
-						status = REJECTED_CURRENT;
-						break;
-					} catch (JGitInternalException e) {
-						throw new CoreException(Activator.error(e.getMessage(), e));
-					} catch (GitAPIException e) {
-						throw new CoreException(Activator.error(e.getMessage(), e));
-					}
-					actMonitor.worked(1);
-				}
-				actMonitor.done();
-			}
-		};
-		// lock workspace to protect working tree changes
-		ResourcesPlugin.getWorkspace().run(action, monitor);
-	}
-
-	public ISchedulingRule getSchedulingRule() {
-		return ResourcesPlugin.getWorkspace().getRoot();
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/DeletePathsOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/DeletePathsOperation.java
deleted file mode 100644
index 6fd3da2..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/DeletePathsOperation.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2012, Robin Stocker <robin@nibor.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.op;
-
-import java.io.File;
-import java.io.IOException;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IWorkspace;
-import org.eclipse.core.resources.IWorkspaceRunnable;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.core.runtime.jobs.ISchedulingRule;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.CoreText;
-import org.eclipse.egit.core.internal.indexdiff.IndexDiffCache;
-import org.eclipse.egit.core.internal.indexdiff.IndexDiffCacheEntry;
-import org.eclipse.egit.core.internal.job.RuleUtil;
-import org.eclipse.egit.core.internal.util.ResourceUtil;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.util.FileUtils;
-
-/**
- * Operation to delete a collection of (untracked) paths, even it they are
- * non-workspace resources.
- */
-public class DeletePathsOperation implements IEGitOperation {
-
-	private final Collection<IPath> paths;
-
-	private final ISchedulingRule schedulingRule;
-
-	/**
-	 * @param paths
-	 *            the files to delete
-	 */
-	public DeletePathsOperation(final Collection<IPath> paths) {
-		this.paths = paths;
-		schedulingRule = calculateSchedulingRule();
-	}
-
-	public void execute(IProgressMonitor m) throws CoreException {
-		IProgressMonitor monitor = (m != null) ? m : new NullProgressMonitor();
-		IWorkspaceRunnable action = new IWorkspaceRunnable() {
-			public void run(IProgressMonitor actMonitor) throws CoreException {
-				deletePaths(actMonitor);
-			}
-		};
-		ResourcesPlugin.getWorkspace().run(action, getSchedulingRule(),
-				IWorkspace.AVOID_UPDATE, monitor);
-	}
-
-	public ISchedulingRule getSchedulingRule() {
-		return schedulingRule;
-	}
-
-	private void deletePaths(IProgressMonitor monitor) throws CoreException {
-		monitor.beginTask(CoreText.DeleteResourcesOperation_deletingResources,
-				paths.size() + 1);
-		boolean errorOccurred = false;
-
-		boolean refreshAll = false;
-		List<IPath> refreshCachePaths = new ArrayList<IPath>();
-
-		for (IPath path : paths) {
-			IResource resource = ResourceUtil.getResourceForLocation(path);
-			if (resource != null && resource.exists())
-				resource.delete(false, new SubProgressMonitor(monitor, 1));
-			else {
-				File file = path.toFile();
-				if (file.exists()) {
-					try {
-						FileUtils.delete(file, FileUtils.RECURSIVE);
-					} catch (IOException e) {
-						errorOccurred = true;
-						String message = MessageFormat
-								.format(CoreText.DeleteResourcesOperation_deleteFailed,
-										file.getPath());
-						Activator.logError(message, e);
-					}
-					refreshCachePaths.add(path);
-					// Selectively refreshing an IndexDiffCacheEntry only works for files,
-					// so refresh all in case of a directory
-					if (file.isDirectory())
-						refreshAll = true;
-				}
-				monitor.worked(1);
-			}
-		}
-
-		if (!refreshCachePaths.isEmpty())
-			refreshIndexDiffCache(refreshCachePaths, refreshAll);
-		monitor.worked(1);
-
-		monitor.done();
-
-		if (errorOccurred) {
-			IStatus status = Activator.error(
-					CoreText.DeleteResourcesOperation_deleteFailedSeeLog, null);
-			throw new CoreException(status);
-		}
-	}
-
-	private ISchedulingRule calculateSchedulingRule() {
-		return RuleUtil.getRuleForContainers(paths);
-	}
-
-	private void refreshIndexDiffCache(List<IPath> refreshCachePaths, boolean refreshAll) {
-		Map<Repository, Collection<String>> resourcesByRepository = ResourceUtil.splitPathsByRepository(refreshCachePaths);
-		for (Map.Entry<Repository, Collection<String>> entry : resourcesByRepository.entrySet()) {
-			Repository repository = entry.getKey();
-			Collection<String> files = entry.getValue();
-
-			IndexDiffCache cache = Activator.getDefault().getIndexDiffCache();
-			IndexDiffCacheEntry cacheEntry = cache.getIndexDiffCacheEntry(repository);
-			if (cacheEntry != null)
-				if (refreshAll)
-					cacheEntry.refresh();
-				else
-					cacheEntry.refreshFiles(files);
-		}
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/DeleteTagOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/DeleteTagOperation.java
deleted file mode 100644
index b9c706d..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/DeleteTagOperation.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/******************************************************************************
- *  Copyright (c) 2011 GitHub Inc.
- *  All rights reserved. This program and the accompanying materials
- *  are made available under the terms of the Eclipse Public License v1.0
- *  which accompanies this distribution, and is available at
- *  http://www.eclipse.org/legal/epl-v10.html
- *
- *  Contributors:
- *    Kevin Sawicki (GitHub Inc.) - initial API and implementation
- *****************************************************************************/
-package org.eclipse.egit.core.op;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.jobs.ISchedulingRule;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.CoreText;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.api.errors.GitAPIException;
-import org.eclipse.jgit.lib.Repository;
-
-/**
- * Operation that deletes a tag
- */
-public class DeleteTagOperation implements IEGitOperation {
-
-	private final Repository repository;
-
-	private final String tag;
-
-	/**
-	 * Create operation that deletes a single tag
-	 *
-	 * @param repository
-	 * @param tag
-	 */
-	public DeleteTagOperation(final Repository repository, final String tag) {
-		this.repository = repository;
-		this.tag = tag;
-	}
-
-	public void execute(IProgressMonitor monitor) throws CoreException {
-		try {
-			Git.wrap(repository).tagDelete().setTags(tag).call();
-		} catch (GitAPIException e) {
-			throw new CoreException(Activator.error(
-					CoreText.DeleteTagOperation_exceptionMessage, e));
-		}
-	}
-
-	public ISchedulingRule getSchedulingRule() {
-		return null;
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/DiscardChangesOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/DiscardChangesOperation.java
deleted file mode 100644
index d1e4ab5..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/DiscardChangesOperation.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2010, Jens Baumgart <jens.baumgart@sap.com>
- * Copyright (C) 2010, Roland Grunberg <rgrunber@redhat.com>
- * Copyright (C) 2012, Robin Stocker <robin@nibor.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Code extracted from org.eclipse.egit.ui.internal.actions.DiscardChangesAction
- * and reworked.
- *******************************************************************************/
-package org.eclipse.egit.core.op;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IResourceRuleFactory;
-import org.eclipse.core.resources.IWorkspace;
-import org.eclipse.core.resources.IWorkspaceRunnable;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.core.runtime.jobs.ISchedulingRule;
-import org.eclipse.core.runtime.jobs.MultiRule;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.CoreText;
-import org.eclipse.egit.core.internal.job.RuleUtil;
-import org.eclipse.egit.core.internal.util.ProjectUtil;
-import org.eclipse.egit.core.internal.util.ResourceUtil;
-import org.eclipse.jgit.api.CheckoutCommand;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.api.errors.GitAPIException;
-import org.eclipse.jgit.lib.Repository;
-
-/**
- * The operation discards changes on a set of resources. In case of a folder
- * resource all file resources in the sub tree are processed. Untracked files
- * are ignored.
- */
-public class DiscardChangesOperation implements IEGitOperation {
-
-	String revision;
-
-	IResource[] files;
-
-	ISchedulingRule schedulingRule;
-
-	/**
-	 * Construct a {@link DiscardChangesOperation} object.
-	 *
-	 * @param files
-	 */
-	public DiscardChangesOperation(IResource[] files) {
-		this(files, null);
-	}
-
-	/**
-	 * Construct a {@link DiscardChangesOperation} object.
-	 *
-	 * @param files
-	 * @param revision
-	 */
-	public DiscardChangesOperation(IResource[] files, String revision) {
-		this.files = new IResource[files.length];
-		System.arraycopy(files, 0, this.files, 0, files.length);
-		this.revision = revision;
-		schedulingRule = MultiRule.combine(calcRefreshRule(files),
-				RuleUtil.getRuleForRepositories(files));
-	}
-
-	/*
-	 * (non-Javadoc)
-	 *
-	 * @see org.eclipse.egit.core.op.IEGitOperation#getSchedulingRule()
-	 */
-	public ISchedulingRule getSchedulingRule() {
-		return schedulingRule;
-	}
-
-	private static ISchedulingRule calcRefreshRule(IResource[] resources) {
-		List<ISchedulingRule> rules = new ArrayList<ISchedulingRule>();
-		IResourceRuleFactory ruleFactory = ResourcesPlugin.getWorkspace()
-				.getRuleFactory();
-		for (IResource resource : resources) {
-			ISchedulingRule rule = ruleFactory.refreshRule(resource);
-			if (rule != null)
-				rules.add(rule);
-		}
-		if (rules.size() == 0)
-			return null;
-		else
-			return new MultiRule(rules.toArray(new IResource[rules.size()]));
-	}
-
-	public void execute(IProgressMonitor m) throws CoreException {
-		IProgressMonitor monitor;
-		if (m == null)
-			monitor = new NullProgressMonitor();
-		else
-			monitor = m;
-		IWorkspaceRunnable action = new IWorkspaceRunnable() {
-			public void run(IProgressMonitor actMonitor) throws CoreException {
-				discardChanges(actMonitor);
-			}
-		};
-		ResourcesPlugin.getWorkspace().run(action, getSchedulingRule(),
-				IWorkspace.AVOID_UPDATE, monitor);
-	}
-
-	private void discardChanges(IProgressMonitor monitor) throws CoreException {
-		monitor.beginTask(CoreText.DiscardChangesOperation_discardingChanges, 2);
-		boolean errorOccurred = false;
-		try {
-			discardChanges();
-		} catch (GitAPIException e) {
-			errorOccurred = true;
-			Activator.logError(CoreText.DiscardChangesOperation_discardFailed, e);
-		}
-		monitor.worked(1);
-		try {
-			ProjectUtil.refreshResources(files, new SubProgressMonitor(monitor,
-					1));
-		} catch (CoreException e) {
-			errorOccurred = true;
-			Activator.logError(CoreText.DiscardChangesOperation_refreshFailed,
-					e);
-		}
-		monitor.worked(1);
-		monitor.done();
-		if (errorOccurred) {
-			IStatus status = Activator.error(
-					CoreText.DiscardChangesOperation_discardFailedSeeLog, null);
-			throw new CoreException(status);
-		}
-	}
-
-	private void discardChanges() throws GitAPIException {
-		Map<Repository, Collection<String>> pathsByRepository = ResourceUtil
-				.splitResourcesByRepository(files);
-		for (Entry<Repository, Collection<String>> entry : pathsByRepository.entrySet()) {
-			Repository repository = entry.getKey();
-			Collection<String> paths = entry.getValue();
-			CheckoutCommand checkoutCommand = new Git(repository).checkout();
-			checkoutCommand.setStartPoint(this.revision);
-			if (paths.isEmpty() || paths.contains("")) //$NON-NLS-1$
-				checkoutCommand.setAllPaths(true);
-			else
-				for (String path : paths)
-					checkoutCommand.addPath(path);
-			checkoutCommand.call();
-		}
-	}
-
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/DisconnectProviderOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/DisconnectProviderOperation.java
deleted file mode 100644
index 29be677..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/DisconnectProviderOperation.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2007, Shawn O. Pearce <spearce@spearce.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.op;
-
-import java.util.Collection;
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.core.runtime.jobs.ISchedulingRule;
-import org.eclipse.core.runtime.jobs.MultiRule;
-import org.eclipse.egit.core.CoreText;
-import org.eclipse.egit.core.internal.trace.GitTraceLocation;
-import org.eclipse.team.core.RepositoryProvider;
-
-/**
- * Disconnects the Git team provider from a project.
- * <p>
- * Once disconnected, Git operations will no longer be available on the project.
- * </p>
- */
-public class DisconnectProviderOperation implements IEGitOperation {
-	private final Collection<IProject> projectList;
-
-	/**
-	 * Create a new disconnect operation.
-	 *
-	 * @param projs
-	 *            the collection of {@link IProject}s which should be
-	 *            disconnected from the Git team provider, and returned to
-	 *            untracked/unmanaged status.
-	 */
-	public DisconnectProviderOperation(final Collection<IProject> projs) {
-		projectList = projs;
-	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.egit.core.op.IEGitOperation#execute(org.eclipse.core.runtime.IProgressMonitor)
-	 */
-	public void execute(IProgressMonitor m) throws CoreException {
-		IProgressMonitor monitor;
-		if (m == null)
-			monitor = new NullProgressMonitor();
-		else
-			monitor = m;
-
-		monitor.beginTask(CoreText.DisconnectProviderOperation_disconnecting,
-				projectList.size() * 200);
-		try {
-			for (IProject p : projectList) {
-				// TODO is this the right location?
-				if (GitTraceLocation.CORE.isActive())
-					GitTraceLocation.getTrace().trace(
-							GitTraceLocation.CORE.getLocation(),
-							"disconnect " + p.getName()); //$NON-NLS-1$
-				unmarkTeamPrivate(p);
-				RepositoryProvider.unmap(p);
-				monitor.worked(100);
-
-				p.refreshLocal(IResource.DEPTH_INFINITE,
-						new SubProgressMonitor(monitor, 100));
-			}
-		} finally {
-			monitor.done();
-		}
-	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.egit.core.op.IEGitOperation#getSchedulingRule()
-	 */
-	public ISchedulingRule getSchedulingRule() {
-		return new MultiRule(projectList.toArray(new IProject[projectList.size()]));
-	}
-
-	private void unmarkTeamPrivate(final IContainer p) throws CoreException {
-		final IResource[] c;
-		c = p.members(IContainer.INCLUDE_TEAM_PRIVATE_MEMBERS);
-		if (c != null) {
-			for (int k = 0; k < c.length; k++) {
-				if (c[k] instanceof IContainer) {
-					unmarkTeamPrivate((IContainer) c[k]);
-				}
-				if (c[k].isTeamPrivateMember()) {
-					// TODO is this the right location?
-					if (GitTraceLocation.CORE.isActive())
-						GitTraceLocation.getTrace().trace(
-								GitTraceLocation.CORE.getLocation(),
-								"notTeamPrivate " + c[k]); //$NON-NLS-1$
-					c[k].setTeamPrivateMember(false);
-				}
-			}
-		}
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/FetchOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/FetchOperation.java
deleted file mode 100644
index fa6950e..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/FetchOperation.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2011, Mathias Kinzler <mathias.kinzler@sap.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.op;
-
-import java.lang.reflect.InvocationTargetException;
-import java.util.List;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.egit.core.CoreText;
-import org.eclipse.egit.core.EclipseGitProgressTransformer;
-import org.eclipse.jgit.api.FetchCommand;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.api.errors.JGitInternalException;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.transport.CredentialsProvider;
-import org.eclipse.jgit.transport.FetchResult;
-import org.eclipse.jgit.transport.RefSpec;
-import org.eclipse.jgit.transport.RemoteConfig;
-import org.eclipse.jgit.transport.TagOpt;
-import org.eclipse.jgit.transport.URIish;
-
-/**
- * Used to fetch from another Repository
- */
-public class FetchOperation {
-	private final Repository repository;
-
-	private final RemoteConfig rc;
-
-	private final URIish uri;
-
-	private final int timeout;
-
-	private final List<RefSpec> specs;
-
-	private final boolean dryRun;
-
-	private FetchResult operationResult;
-
-	private CredentialsProvider credentialsProvider;
-
-	private TagOpt tagOpt;
-
-	/**
-	 * Constructs a FetchOperation based on URI and RefSpecs
-	 *
-	 * @param repository
-	 * @param uri
-	 * @param refSpecs
-	 * @param timeout
-	 * @param dryRun
-	 *
-	 */
-	public FetchOperation(Repository repository, URIish uri,
-			List<RefSpec> refSpecs, int timeout, boolean dryRun) {
-		this.repository = repository;
-		this.timeout = timeout;
-		this.dryRun = dryRun;
-		this.uri = uri;
-		this.specs = refSpecs;
-		this.rc = null;
-	}
-
-	/**
-	 * Constructs a FetchOperation based on a RemoteConfig
-	 *
-	 * @param repository
-	 * @param config
-	 * @param timeout
-	 * @param dryRun
-	 */
-	public FetchOperation(Repository repository, RemoteConfig config,
-			int timeout, boolean dryRun) {
-		this.repository = repository;
-		this.timeout = timeout;
-		this.dryRun = dryRun;
-		this.uri = null;
-		this.specs = null;
-		this.rc = config;
-	}
-
-	/**
-	 * @param credentialsProvider
-	 */
-	public void setCredentialsProvider(CredentialsProvider credentialsProvider) {
-		this.credentialsProvider = credentialsProvider;
-	}
-
-	/**
-	 * @param tagOpt
-	 */
-	public void setTagOpt(TagOpt tagOpt) {
-		this.tagOpt = tagOpt;
-	}
-
-	/**
-	 * @param monitor
-	 * @throws InvocationTargetException
-	 */
-	public void run(IProgressMonitor monitor) throws InvocationTargetException {
-		if (operationResult != null)
-			throw new IllegalStateException(CoreText.OperationAlreadyExecuted);
-
-		IProgressMonitor actMonitor = monitor;
-		if (actMonitor == null)
-			actMonitor = new NullProgressMonitor();
-		EclipseGitProgressTransformer gitMonitor = new EclipseGitProgressTransformer(
-				actMonitor);
-		FetchCommand command;
-		if (rc == null)
-			command = new Git(repository).fetch().setRemote(
-					uri.toPrivateString()).setRefSpecs(specs);
-		else
-			command = new Git(repository).fetch().setRemote(rc.getName());
-		command.setCredentialsProvider(credentialsProvider).setTimeout(timeout)
-				.setDryRun(dryRun).setProgressMonitor(gitMonitor);
-		if (tagOpt != null)
-			command.setTagOpt(tagOpt);
-		try {
-			operationResult = command.call();
-		} catch (JGitInternalException e) {
-			throw new InvocationTargetException(e.getCause() != null ? e
-					.getCause() : e);
-		} catch (Exception e) {
-			throw new InvocationTargetException(e);
-		}
-	}
-
-	/**
-	 * @return the result, or <code>null</code> if the operation has not been
-	 *         executed
-	 */
-	public FetchResult getOperationResult() {
-		return operationResult;
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/FetchOperationResult.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/FetchOperationResult.java
deleted file mode 100644
index a5f5e5b..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/FetchOperationResult.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2010, Mathias Kinzler <mathias.kinzler@sap.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.op;
-
-import org.eclipse.jgit.transport.FetchResult;
-import org.eclipse.jgit.transport.URIish;
-
-/**
- * Stores the result of a fetch operation
- */
-public class FetchOperationResult {
-	private final URIish uri;
-
-	private final FetchResult fetchResult;
-
-	private final String fetchErrorMessage;
-
-	/**
-	 * @param uri
-	 * @param result
-	 */
-	public FetchOperationResult(URIish uri, FetchResult result) {
-		this.uri = uri;
-		this.fetchResult = result;
-		this.fetchErrorMessage = null;
-	}
-
-	/**
-	 * @param uri
-	 * @param errorMessage
-	 */
-	public FetchOperationResult(URIish uri, String errorMessage) {
-		this.uri = uri;
-		this.fetchResult = null;
-		this.fetchErrorMessage = errorMessage;
-	}
-
-	/**
-	 * @return the URI
-	 *
-	 */
-	public URIish getURI() {
-		return uri;
-	}
-
-	/**
-	 * @return the result
-	 */
-	public FetchResult getFetchResult() {
-		return fetchResult;
-	}
-
-	/**
-	 * @return the error message
-	 */
-	public String getErrorMessage() {
-		return fetchErrorMessage;
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/GarbageCollectOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/GarbageCollectOperation.java
deleted file mode 100644
index 54263f2..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/GarbageCollectOperation.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2012, Matthias Sohn <matthias.sohn@sap.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.op;
-
-import java.io.IOException;
-import java.text.ParseException;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.jobs.ISchedulingRule;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.EclipseGitProgressTransformer;
-import org.eclipse.egit.core.internal.job.RuleUtil;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.internal.storage.file.FileRepository;
-import org.eclipse.jgit.internal.storage.file.GC;
-
-/**
- * Operation to garbage collect a git repository
- */
-public class GarbageCollectOperation implements IEGitOperation {
-
-	private Repository repository;
-
-	/**
-	 * @param repository the repository to garbage collect
-	 */
-	public GarbageCollectOperation(Repository repository) {
-		this.repository = repository;
-	}
-
-	/**
-	 * Execute garbage collection
-	 */
-	public void execute(IProgressMonitor monitor) throws CoreException {
-		GC gc = new GC((FileRepository) repository);
-		gc.setProgressMonitor(new EclipseGitProgressTransformer(
-				monitor));
-		try {
-			gc.gc();
-		} catch (IOException e) {
-			throw new CoreException(new Status(IStatus.ERROR,
-					Activator.getPluginId(), e.getMessage(), e));
-		} catch (ParseException e) {
-			throw new CoreException(new Status(IStatus.ERROR,
-					Activator.getPluginId(), e.getMessage(), e));
-		}
-	}
-
-	public ISchedulingRule getSchedulingRule() {
-		return RuleUtil.getRule(repository);
-	}
-
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/IEGitOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/IEGitOperation.java
deleted file mode 100644
index b036c0c..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/IEGitOperation.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2010, Jens Baumgart <jens.baumgart@sap.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.op;
-
-import org.eclipse.core.resources.IResourceRuleFactory;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.jobs.ISchedulingRule;
-import org.eclipse.jgit.lib.Repository;
-
-/**
- * interface for EGit operations
- *
- */
-public interface IEGitOperation {
-	/**
-	 * Executes the operation
-	 *
-	 * @param monitor
-	 *            a progress monitor, or <code>null</code> if progress reporting
-	 *            and cancellation are not desired
-	 * @throws CoreException
-	 */
-	void execute(IProgressMonitor monitor) throws CoreException;
-
-	/**
-	 * @return the rule needed to execute this operation.
-	 * <code>null</code> if no rule is required.
-	 * A rule is required if the operation changes resources.
-	 * It can also be useful to use a rule for reading resources to avoid
-	 * changes on the resources by other threads while the operation is running.
-	 * @see IResourceRuleFactory
-	 */
-	ISchedulingRule getSchedulingRule();
-
-	/**
-	 * A task to be performed before execution begins
-	 */
-	interface PreExecuteTask {
-
-		/**
-		 * Executes the task
-		 *
-		 * @param repository
-		 *            the git repository
-		 *
-		 * @param monitor
-		 *            a progress monitor, or <code>null</code> if progress
-		 *            reporting and cancellation are not desired
-		 * @throws CoreException
-		 */
-		void preExecute(Repository repository, IProgressMonitor monitor)
-				throws CoreException;
-	}
-
-	/**
-	 * A task to be performed after execution completes
-	 */
-	interface PostExecuteTask {
-
-		/**
-		 * Executes the task
-		 *
-		 * @param repository
-		 *            the git repository
-		 *
-		 * @param monitor
-		 *            a progress monitor, or <code>null</code> if progress
-		 *            reporting and cancellation are not desired
-		 * @throws CoreException
-		 */
-		void postExecute(Repository repository, IProgressMonitor monitor)
-				throws CoreException;
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/IgnoreOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/IgnoreOperation.java
deleted file mode 100644
index 1a58189..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/IgnoreOperation.java
+++ /dev/null
@@ -1,222 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2009, Alex Blewitt <alex.blewitt@gmail.com>
- * Copyright (C) 2010, Jens Baumgart <jens.baumgart@sap.com>
- * Copyright (C) 2012, 2013 Robin Stocker <robin@nibor.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.op;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.io.UnsupportedEncodingException;
-import java.nio.ByteBuffer;
-import java.nio.channels.FileChannel;
-import java.util.ArrayList;
-import java.util.Collection;
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IWorkspaceRoot;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.core.runtime.jobs.ISchedulingRule;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.CoreText;
-import org.eclipse.egit.core.RepositoryUtil;
-import org.eclipse.egit.core.internal.job.RuleUtil;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.osgi.util.NLS;
-
-/**
- * IgnoreOperation adds resources to a .gitignore file
- *
- */
-public class IgnoreOperation implements IEGitOperation {
-
-	private final Collection<IPath> paths;
-
-	private boolean gitignoreOutsideWSChanged;
-
-	private ISchedulingRule schedulingRule;
-
-	/**
-	 * construct an IgnoreOperation
-	 *
-	 * @param paths
-	 * @since 2.2
-	 */
-	public IgnoreOperation(Collection<IPath> paths) {
-		this.paths = paths;
-		gitignoreOutsideWSChanged = false;
-		schedulingRule = calcSchedulingRule();
-	}
-
-	/**
-	 * @param resources
-	 * @deprecated use {@link #IgnoreOperation(Collection)}
-	 */
-	@Deprecated
-	public IgnoreOperation(IResource[] resources) {
-		paths = new ArrayList<IPath>(resources.length);
-		for (IResource resource : resources) {
-			IPath location = resource.getLocation();
-			if (location != null)
-				paths.add(location);
-		}
-	}
-
-	public void execute(IProgressMonitor monitor) throws CoreException {
-		monitor.beginTask(CoreText.IgnoreOperation_taskName, paths.size());
-		try {
-			for (IPath path : paths) {
-				if (monitor.isCanceled())
-					break;
-				// TODO This is pretty inefficient; multiple ignores in
-				// the same directory cause multiple writes.
-
-				// NB This does the same thing in
-				// DecoratableResourceAdapter, but neither currently
-				// consult .gitignore
-				if (!RepositoryUtil.isIgnored(path))
-					addIgnore(monitor, path);
-				monitor.worked(1);
-			}
-			monitor.done();
-		} catch (CoreException e) {
-			throw e;
-		} catch (Exception e) {
-			throw new CoreException(Activator.error(
-					CoreText.IgnoreOperation_error, e));
-		}
-	}
-
-	/**
-	 * @return true if a gitignore file outside the workspace was changed. In
-	 *         this case the caller may need to perform manual UI refreshes
-	 *         because there was no ResourceChanged event.
-	 */
-	public boolean isGitignoreOutsideWSChanged() {
-		return gitignoreOutsideWSChanged;
-	}
-
-	public ISchedulingRule getSchedulingRule() {
-		return schedulingRule;
-	}
-
-	private void addIgnore(IProgressMonitor monitor, IPath path)
-			throws UnsupportedEncodingException, CoreException, IOException {
-		IPath parent = path.removeLastSegments(1);
-		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
-		IContainer container = root.getContainerForLocation(parent);
-
-		String entry = "/" + path.lastSegment() + "\n"; //$NON-NLS-1$  //$NON-NLS-2$
-
-		if (container == null || container instanceof IWorkspaceRoot) {
-			Repository repository = RepositoryMapping.getMapping(
-					path).getRepository();
-			// .gitignore is not accessible as resource
-			IPath gitIgnorePath = parent.append(Constants.GITIGNORE_FILENAME);
-			IPath repoPath = new Path(repository.getWorkTree()
-					.getAbsolutePath());
-			if (!repoPath.isPrefixOf(gitIgnorePath)) {
-				String message = NLS.bind(
-						CoreText.IgnoreOperation_parentOutsideRepo,
-						path.toOSString(), repoPath.toOSString());
-				IStatus status = Activator.error(message, null);
-				throw new CoreException(status);
-			}
-			File gitIgnore = new File(gitIgnorePath.toOSString());
-			updateGitIgnore(gitIgnore, entry);
-			// no resource change event when updating .gitignore outside
-			// workspace => trigger manual decorator refresh
-			gitignoreOutsideWSChanged = true;
-		} else {
-			IFile gitignore = container.getFile(new Path(
-					Constants.GITIGNORE_FILENAME));
-			entry = getEntry(gitignore.getLocation().toFile(), entry);
-			IProgressMonitor subMonitor = new SubProgressMonitor(monitor, 1);
-			ByteArrayInputStream entryBytes = asStream(entry);
-			if (gitignore.exists())
-				gitignore.appendContents(entryBytes, true, true, subMonitor);
-			else
-				gitignore.create(entryBytes, true, subMonitor);
-		}
-	}
-
-	private boolean prependNewline(File file) throws IOException {
-		boolean prepend = false;
-		long length = file.length();
-		if (length > 0) {
-			RandomAccessFile raf = new RandomAccessFile(file, "r"); //$NON-NLS-1$
-			try {
-				// Read the last byte and see if it is a newline
-				ByteBuffer buffer = ByteBuffer.allocate(1);
-				FileChannel channel = raf.getChannel();
-				channel.position(length - 1);
-				if (channel.read(buffer) > 0) {
-					buffer.rewind();
-					prepend = buffer.get() != '\n';
-				}
-			} finally {
-				raf.close();
-			}
-		}
-		return prepend;
-	}
-
-	private String getEntry(File file, String entry) throws IOException {
-		return prependNewline(file) ? "\n" + entry : entry; //$NON-NLS-1$
-	}
-
-	private void updateGitIgnore(File gitIgnore, String entry)
-			throws CoreException {
-		try {
-			String ignoreLine = entry;
-			if (!gitIgnore.exists())
-				if (!gitIgnore.createNewFile()) {
-					String error = NLS.bind(
-							CoreText.IgnoreOperation_creatingFailed,
-							gitIgnore.getAbsolutePath());
-					throw new CoreException(Activator.error(error, null));
-				}
-			else
-				ignoreLine = getEntry(gitIgnore, ignoreLine);
-
-			FileOutputStream os = new FileOutputStream(gitIgnore, true);
-			try {
-				os.write(ignoreLine.getBytes());
-			} finally {
-				os.close();
-			}
-		} catch (IOException e) {
-			String error = NLS.bind(CoreText.IgnoreOperation_updatingFailed,
-					gitIgnore.getAbsolutePath());
-			throw new CoreException(Activator.error(error, e));
-		}
-	}
-
-	private ByteArrayInputStream asStream(String entry)
-			throws UnsupportedEncodingException {
-		return new ByteArrayInputStream(
-				entry.getBytes(Constants.CHARACTER_ENCODING));
-	}
-
-	private ISchedulingRule calcSchedulingRule() {
-		return RuleUtil.getRuleForContainers(paths);
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/ListRemoteOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/ListRemoteOperation.java
deleted file mode 100644
index 40ce4ef..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/ListRemoteOperation.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.com>
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.op;
-
-import java.lang.reflect.InvocationTargetException;
-import java.util.Collection;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.egit.core.CoreText;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.api.LsRemoteCommand;
-import org.eclipse.jgit.api.errors.GitAPIException;
-import org.eclipse.jgit.api.errors.JGitInternalException;
-import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.transport.CredentialsProvider;
-import org.eclipse.jgit.transport.URIish;
-
-/**
- * Operation of listing remote repository advertised refs.
- */
-public class ListRemoteOperation {
-	private final LsRemoteCommand rc;
-
-	private Collection<Ref> remoteRefs;
-
-	/**
-	 * Create listing operation for specified local repository (needed by
-	 * transport) and remote repository URI.
-	 *
-	 * @param localDb
-	 *            local repository (needed for transport) where fetch would
-	 *            occur.
-	 * @param uri
-	 *            URI of remote repository to list.
-	 * @param timeout
-	 *            timeout is seconds; 0 means no timeout
-	 */
-	public ListRemoteOperation(final Repository localDb, final URIish uri,
-			int timeout) {
-		Git git = new Git(localDb);
-		rc = git.lsRemote();
-		rc.setRemote(uri.toString()).setTimeout(timeout);
-	}
-
-	/**
-	 * @return collection of refs advertised by remote side.
-	 * @throws IllegalStateException
-	 *             if error occurred during earlier remote refs listing.
-	 */
-	public Collection<Ref> getRemoteRefs() {
-		checkState();
-		return remoteRefs;
-	}
-
-	/**
-	 * @param refName
-	 *            remote ref name to search for.
-	 * @return ref with specified refName or null if not found.
-	 * @throws IllegalStateException
-	 *             if error occurred during earlier remote refs listing.
-	 */
-	public Ref getRemoteRef(final String refName) {
-		checkState();
-		for (Ref r: remoteRefs)
-			if (r.getName().equals(refName))
-				return r;
-		return null;
-	}
-
-	/**
-	 * Sets a credentials provider
-	 * @param credentialsProvider
-	 */
-	public void setCredentialsProvider(CredentialsProvider credentialsProvider) {
-		rc.setCredentialsProvider(credentialsProvider);
-	}
-
-	/**
-	 * @param pm
-	 *            the monitor to be used for reporting progress and responding
-	 *            to cancellation. The monitor is never <code>null</code>
-	 * @throws InvocationTargetException
-	 * @throws InterruptedException
-	 */
-	public void run(IProgressMonitor pm) throws InvocationTargetException,
-			InterruptedException {
-		if (pm != null)
-			pm.beginTask(CoreText.ListRemoteOperation_title,
-					IProgressMonitor.UNKNOWN);
-		try {
-			remoteRefs = rc.call();
-		} catch (JGitInternalException e) {
-			throw new InvocationTargetException(e);
-		} catch (GitAPIException e) {
-			throw new InvocationTargetException(e);
-		}
-		if (pm != null)
-			pm.done();
-	}
-
-	private void checkState() {
-		if (remoteRefs == null)
-			throw new IllegalStateException(
-					"Error occurred during remote repo " +  //$NON-NLS-1$
-					"listing, no refs available"); //$NON-NLS-1$
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/MergeOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/MergeOperation.java
deleted file mode 100644
index 2bf0eef..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/MergeOperation.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010 SAP AG.
- * Copyright (C) 2012, 2013 Tomasz Zarna <tzarna@gmail.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *    Stefan Lay (SAP AG) - initial implementation
- *    Tomasz Zarna (IBM) - merge squash, bug 382720
- *******************************************************************************/
-package org.eclipse.egit.core.op;
-
-import java.io.IOException;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IWorkspaceRunnable;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.core.runtime.jobs.ISchedulingRule;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.CoreText;
-import org.eclipse.egit.core.internal.util.ProjectUtil;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.api.MergeCommand;
-import org.eclipse.jgit.api.MergeCommand.FastForwardMode;
-import org.eclipse.jgit.api.MergeResult;
-import org.eclipse.jgit.api.errors.CheckoutConflictException;
-import org.eclipse.jgit.api.errors.ConcurrentRefUpdateException;
-import org.eclipse.jgit.api.errors.GitAPIException;
-import org.eclipse.jgit.api.errors.NoHeadException;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.merge.MergeStrategy;
-import org.eclipse.osgi.util.NLS;
-import org.eclipse.team.core.TeamException;
-
-/**
- * This class implements the merge of a ref with the current head
- *
- */
-public class MergeOperation implements IEGitOperation {
-
-	private final Repository repository;
-
-	private final String refName;
-
-	private MergeStrategy mergeStrategy;
-
-	private boolean squash;
-
-	private FastForwardMode fastForwardMode;
-
-	private MergeResult mergeResult;
-
-	/**
-	 * @param repository
-	 * @param refName name of a commit which should be merged
-	 */
-	public MergeOperation(Repository repository, String refName) {
-		this.repository = repository;
-		this.refName = refName;
-	}
-
-	/**
-	* Create a MergeOperation object
-	* @param repository
-	* @param refName name of a commit which should be merged
-	* @param mergeStrategy the strategy to use for merge
-	*/
-	public MergeOperation(Repository repository, String refName,
-		String mergeStrategy) {
-		this.repository = repository;
-		this.refName = refName;
-		if (mergeStrategy != null)
-			this.mergeStrategy = MergeStrategy.get(mergeStrategy);
-	}
-
-	/**
-	 * @param squash true to squash merge commits
-	 */
-	public void setSquash(boolean squash) {
-		this.squash = squash;
-	}
-
-	/**
-	 * @param ffmode set the fast forward mode
-	 */
-	public void setFastForwardMode(FastForwardMode ffmode) {
-		this.fastForwardMode = ffmode;
-	}
-
-	public void execute(IProgressMonitor m) throws CoreException {
-		if (mergeResult != null)
-			throw new CoreException(new Status(IStatus.ERROR, Activator
-					.getPluginId(), CoreText.OperationAlreadyExecuted));
-		IProgressMonitor monitor;
-		if (m == null)
-			monitor = new NullProgressMonitor();
-		else
-			monitor = m;
-		IWorkspaceRunnable action = new IWorkspaceRunnable() {
-
-			public void run(IProgressMonitor mymonitor) throws CoreException {
-				IProject[] validProjects = ProjectUtil.getValidOpenProjects(repository);
-				mymonitor.beginTask(NLS.bind(CoreText.MergeOperation_ProgressMerge, refName), 3);
-				Git git = new Git(repository);
-				mymonitor.worked(1);
-				MergeCommand merge;
-				try {
-					FastForwardMode ffmode = fastForwardMode;
-					if (ffmode == null)
-						ffmode = Activator.getDefault().getRepositoryUtil()
-								.getFastForwardMode(repository);
-					Ref ref = repository.getRef(refName);
-					if (ref != null)
-						merge = git.merge().include(ref).setFastForward(ffmode);
-					else
-						merge = git.merge()
-								.include(ObjectId.fromString(refName))
-								.setFastForward(ffmode);
-				} catch (IOException e) {
-					throw new TeamException(CoreText.MergeOperation_InternalError, e);
-				}
-				merge.setSquash(squash);
-				if (mergeStrategy != null) {
-					merge.setStrategy(mergeStrategy);
-				}
-				try {
-					mergeResult = merge.call();
-					mymonitor.worked(1);
-					if (MergeResult.MergeStatus.NOT_SUPPORTED.equals(mergeResult.getMergeStatus()))
-						throw new TeamException(new Status(IStatus.INFO, Activator.getPluginId(), mergeResult.toString()));
-				} catch (NoHeadException e) {
-					throw new TeamException(CoreText.MergeOperation_MergeFailedNoHead, e);
-				} catch (ConcurrentRefUpdateException e) {
-					throw new TeamException(CoreText.MergeOperation_MergeFailedRefUpdate, e);
-				} catch (CheckoutConflictException e) {
-					mergeResult = new MergeResult(e.getConflictingPaths());
-					return;
-				} catch (GitAPIException e) {
-					throw new TeamException(e.getLocalizedMessage(), e.getCause());
-				} finally {
-					ProjectUtil.refreshValidProjects(validProjects, new SubProgressMonitor(
-							mymonitor, 1));
-					mymonitor.done();
-				}
-			}
-		};
-		// lock workspace to protect working tree changes
-		ResourcesPlugin.getWorkspace().run(action, monitor);
-	}
-
-	/**
-	 * @return the merge result, or <code>null</code> if this has not been
-	 *         executed or if an exception occurred
-	 */
-	public MergeResult getResult() {
-		return this.mergeResult;
-	}
-
-	public ISchedulingRule getSchedulingRule() {
-		return ResourcesPlugin.getWorkspace().getRoot();
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/PullOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/PullOperation.java
deleted file mode 100644
index 6e0a0cb..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/PullOperation.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010 SAP AG.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *    Mathias Kinzler <mathias.kinzler@sap.com> - initial implementation
- *******************************************************************************/
-package org.eclipse.egit.core.op;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Set;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IWorkspaceRunnable;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.core.runtime.jobs.ISchedulingRule;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.CoreText;
-import org.eclipse.egit.core.EclipseGitProgressTransformer;
-import org.eclipse.egit.core.internal.util.ProjectUtil;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.api.MergeResult;
-import org.eclipse.jgit.api.MergeResult.MergeStatus;
-import org.eclipse.jgit.api.PullCommand;
-import org.eclipse.jgit.api.PullResult;
-import org.eclipse.jgit.api.errors.DetachedHeadException;
-import org.eclipse.jgit.api.errors.GitAPIException;
-import org.eclipse.jgit.api.errors.InvalidConfigurationException;
-import org.eclipse.jgit.api.errors.JGitInternalException;
-import org.eclipse.jgit.errors.TransportException;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.osgi.util.NLS;
-
-/**
- * Wraps the JGit API {@link PullCommand} into an operation
- */
-public class PullOperation implements IEGitOperation {
-	private final Repository[] repositories;
-
-	private final Map<Repository, Object> results = new LinkedHashMap<Repository, Object>();
-
-	private final int timeout;
-
-	/**
-	 * @param repositories
-	 *            the repository
-	 * @param timeout
-	 *            in seconds
-	 */
-	public PullOperation(Set<Repository> repositories, int timeout) {
-		this.timeout = timeout;
-		this.repositories = repositories.toArray(new Repository[repositories
-				.size()]);
-	}
-
-	public void execute(IProgressMonitor m) throws CoreException {
-		if (!results.isEmpty())
-			throw new CoreException(new Status(IStatus.ERROR, Activator
-					.getPluginId(), CoreText.OperationAlreadyExecuted));
-		IProgressMonitor monitor;
-		if (m == null)
-			monitor = new NullProgressMonitor();
-		else
-			monitor = m;
-		monitor.beginTask(NLS.bind(CoreText.PullOperation_TaskName, Integer
-				.valueOf(repositories.length)), repositories.length * 2);
-		IWorkspaceRunnable action = new IWorkspaceRunnable() {
-			public void run(IProgressMonitor mymonitor) throws CoreException {
-				for (int i = 0; i < repositories.length; i++) {
-					Repository repository = repositories[i];
-					if (mymonitor.isCanceled())
-						throw new CoreException(Status.CANCEL_STATUS);
-					IProject[] validProjects = ProjectUtil.getValidOpenProjects(repository);
-					PullCommand pull = new Git(repository).pull();
-					PullResult pullResult = null;
-					try {
-						pull.setProgressMonitor(new EclipseGitProgressTransformer(
-								new SubProgressMonitor(mymonitor, 1)));
-						pull.setTimeout(timeout);
-						pullResult = pull.call();
-						results.put(repository, pullResult);
-					} catch (DetachedHeadException e) {
-						results.put(repository, Activator.error(
-								CoreText.PullOperation_DetachedHeadMessage, e));
-					} catch (InvalidConfigurationException e) {
-						IStatus error = Activator
-								.error(CoreText.PullOperation_PullNotConfiguredMessage,
-										e);
-						results.put(repository, error);
-					} catch (GitAPIException e) {
-						results.put(repository,
-								Activator.error(e.getMessage(), e));
-					} catch (JGitInternalException e) {
-						Throwable cause = e.getCause();
-						if (cause == null || !(cause instanceof TransportException))
-							cause = e;
-						results.put(repository,
-								Activator.error(cause.getMessage(), cause));
-					} finally {
-						mymonitor.worked(1);
-						if (refreshNeeded(pullResult)) {
-							ProjectUtil.refreshValidProjects(validProjects,
-									new SubProgressMonitor(mymonitor, 1));
-							mymonitor.worked(1);
-						}
-					}
-				}
-			}
-		};
-		// lock workspace to protect working tree changes
-		ResourcesPlugin.getWorkspace().run(action, monitor);
-	}
-
-	private boolean refreshNeeded(PullResult pullResult) {
-		if (pullResult == null)
-			return true;
-		MergeResult mergeResult = pullResult.getMergeResult();
-		if (mergeResult == null)
-			return true;
-		if (mergeResult.getMergeStatus() == MergeStatus.ALREADY_UP_TO_DATE)
-			return false;
-		return true;
-	}
-
-	/**
-	 * @return the results, or an empty Map if this has not been executed
-	 */
-	public Map<Repository, Object> getResults() {
-		return this.results;
-	}
-
-	public ISchedulingRule getSchedulingRule() {
-		return ResourcesPlugin.getWorkspace().getRoot();
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/PushOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/PushOperation.java
deleted file mode 100644
index c708361..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/PushOperation.java
+++ /dev/null
@@ -1,262 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.com>
- * Copyright (C) 2011, Mathias Kinzler <mathias.kinzler@sap.com>
- * Copyright (C) 2012, Robin Stocker <robin@nibor.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.op;
-
-import java.lang.reflect.InvocationTargetException;
-import java.net.URISyntaxException;
-import java.util.Collection;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.CoreText;
-import org.eclipse.egit.core.EclipseGitProgressTransformer;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.api.errors.JGitInternalException;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.transport.CredentialsProvider;
-import org.eclipse.jgit.transport.PushResult;
-import org.eclipse.jgit.transport.RemoteConfig;
-import org.eclipse.jgit.transport.RemoteRefUpdate;
-import org.eclipse.jgit.transport.RemoteRefUpdate.Status;
-import org.eclipse.jgit.transport.Transport;
-import org.eclipse.jgit.transport.URIish;
-import org.eclipse.osgi.util.NLS;
-
-/**
- * Push operation: pushing from local repository to one or many remote ones.
- */
-public class PushOperation {
-	private static final int WORK_UNITS_PER_TRANSPORT = 10;
-
-	private final Repository localDb;
-
-	private final PushOperationSpecification specification;
-
-	private final boolean dryRun;
-
-	private final String remoteName;
-
-	private final int timeout;
-
-	private PushOperationResult operationResult;
-
-	private CredentialsProvider credentialsProvider;
-
-	/**
-	 * Create push operation for provided specification.
-	 *
-	 * @param localDb
-	 *            local repository.
-	 * @param specification
-	 *            specification of ref updates for remote repositories.
-	 * @param dryRun
-	 *            true if push operation should just check for possible result
-	 *            and not really update remote refs, false otherwise - when push
-	 *            should act normally.
-	 * @param timeout
-	 *            the timeout in seconds (0 for no timeout)
-	 */
-	public PushOperation(final Repository localDb,
-			final PushOperationSpecification specification,
-			final boolean dryRun, int timeout) {
-		this.localDb = localDb;
-		this.specification = specification;
-		this.dryRun = dryRun;
-		this.remoteName = null;
-		this.timeout = timeout;
-	}
-
-	/**
-	 * Creates a push operation for a remote configuration.
-	 *
-	 * @param localDb
-	 * @param remoteName
-	 * @param dryRun
-	 * @param timeout
-	 */
-	public PushOperation(final Repository localDb, final String remoteName,
-			final boolean dryRun, int timeout) {
-		this.localDb = localDb;
-		this.specification = null;
-		this.dryRun = dryRun;
-		this.remoteName = remoteName;
-		this.timeout = timeout;
-	}
-
-	/**
-	 * @param credentialsProvider
-	 */
-	public void setCredentialsProvider(CredentialsProvider credentialsProvider) {
-		this.credentialsProvider = credentialsProvider;
-	}
-
-	/**
-	 * @return push operation result
-	 */
-	public PushOperationResult getOperationResult() {
-		if (operationResult == null)
-			throw new IllegalStateException(CoreText.OperationNotYetExecuted);
-		return operationResult;
-	}
-
-	/**
-	 * @return operation specification, as provided in constructor (may be
-	 *         <code>null</code>)
-	 */
-	public PushOperationSpecification getSpecification() {
-		return specification;
-	}
-
-	/**
-	 * @param actMonitor
-	 *            may be <code>null</code> if progress monitoring is not desired
-	 * @throws InvocationTargetException
-	 *             not really used: failure is communicated via the result (see
-	 *             {@link #getOperationResult()})
-	 */
-	public void run(IProgressMonitor actMonitor)
-			throws InvocationTargetException {
-
-		if (operationResult != null)
-			throw new IllegalStateException(CoreText.OperationAlreadyExecuted);
-
-		if (this.specification != null)
-			for (URIish uri : this.specification.getURIs()) {
-				for (RemoteRefUpdate update : this.specification
-						.getRefUpdates(uri))
-					if (update.getStatus() != Status.NOT_ATTEMPTED)
-						throw new IllegalStateException(
-								CoreText.RemoteRefUpdateCantBeReused);
-			}
-		IProgressMonitor monitor;
-		if (actMonitor == null)
-			monitor = new NullProgressMonitor();
-		else
-			monitor = actMonitor;
-
-		final int totalWork;
-		if (specification != null)
-			totalWork = specification.getURIsNumber()
-					* WORK_UNITS_PER_TRANSPORT;
-		else
-			totalWork = 1;
-		if (dryRun)
-			monitor.beginTask(CoreText.PushOperation_taskNameDryRun, totalWork);
-		else
-			monitor.beginTask(CoreText.PushOperation_taskNameNormalRun,
-					totalWork);
-
-		operationResult = new PushOperationResult();
-		Git git = new Git(localDb);
-
-		if (specification != null)
-			for (final URIish uri : specification.getURIs()) {
-				final SubProgressMonitor subMonitor = new SubProgressMonitor(
-						monitor, WORK_UNITS_PER_TRANSPORT,
-						SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK);
-
-				try {
-					if (monitor.isCanceled()) {
-						operationResult.addOperationResult(uri,
-								CoreText.PushOperation_resultCancelled);
-						continue;
-					}
-
-					Collection<RemoteRefUpdate> refUpdates = specification.getRefUpdates(uri);
-					final EclipseGitProgressTransformer gitSubMonitor = new EclipseGitProgressTransformer(
-							subMonitor);
-
-					try {
-						Transport transport = Transport.open(localDb, uri);
-						transport.setDryRun(dryRun);
-						transport.setTimeout(timeout);
-						if (credentialsProvider != null)
-							transport.setCredentialsProvider(credentialsProvider);
-						PushResult result = transport.push(gitSubMonitor, refUpdates);
-
-						operationResult.addOperationResult(result.getURI(), result);
-						specification.addURIRefUpdates(result.getURI(), result.getRemoteUpdates());
-					} catch (JGitInternalException e) {
-						String errorMessage = e.getCause() != null ? e
-								.getCause().getMessage() : e.getMessage();
-						String userMessage = NLS.bind(
-										CoreText.PushOperation_InternalExceptionOccurredMessage,
-										errorMessage);
-						handleException(uri, e, userMessage);
-					} catch (Exception e) {
-						handleException(uri, e, e.getMessage());
-					}
-
-					monitor.worked(WORK_UNITS_PER_TRANSPORT);
-				} finally {
-					// Dirty trick to get things always working.
-					subMonitor.beginTask("", WORK_UNITS_PER_TRANSPORT); //$NON-NLS-1$
-					subMonitor.done();
-					subMonitor.done();
-				}
-			}
-		else {
-			final EclipseGitProgressTransformer gitMonitor = new EclipseGitProgressTransformer(
-					monitor);
-			try {
-				Iterable<PushResult> results = git.push().setRemote(
-						remoteName).setDryRun(dryRun).setTimeout(timeout)
-						.setProgressMonitor(gitMonitor).setCredentialsProvider(
-								credentialsProvider).call();
-				for (PushResult result : results) {
-					operationResult.addOperationResult(result.getURI(), result);
-				}
-			} catch (JGitInternalException e) {
-				String errorMessage = e.getCause() != null ? e.getCause()
-						.getMessage() : e.getMessage();
-				String userMessage = NLS.bind(
-						CoreText.PushOperation_InternalExceptionOccurredMessage,
-						errorMessage);
-				URIish uri = getPushURIForErrorHandling();
-				handleException(uri, e, userMessage);
-			} catch (Exception e) {
-				URIish uri = getPushURIForErrorHandling();
-				handleException(uri, e, e.getMessage());
-			}
-		}
-		monitor.done();
-	}
-
-	private void handleException(final URIish uri, Exception e,
-			String userMessage) {
-		String uriString;
-		if (uri != null) {
-			operationResult.addOperationResult(uri, userMessage);
-			uriString = uri.toString();
-		} else
-			uriString = "retrieving URI failed"; //$NON-NLS-1$
-
-		String userMessageForUri = NLS.bind(
-				CoreText.PushOperation_ExceptionOccurredDuringPushOnUriMessage,
-				uriString, userMessage);
-		Activator.logError(userMessageForUri, e);
-	}
-
-	private URIish getPushURIForErrorHandling() {
-		RemoteConfig rc = null;
-		try {
-			rc = new RemoteConfig(localDb.getConfig(), remoteName);
-			return rc.getPushURIs().isEmpty() ? rc.getURIs().get(0) : rc
-					.getPushURIs().get(0);
-		} catch (URISyntaxException e) {
-			// should not happen
-			Activator.logError("Reading RemoteConfig failed", e); //$NON-NLS-1$
-			return null;
-		}
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/PushOperationResult.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/PushOperationResult.java
deleted file mode 100644
index 4caa0c6..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/PushOperationResult.java
+++ /dev/null
@@ -1,282 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.op;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.Set;
-
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.transport.PushResult;
-import org.eclipse.jgit.transport.RemoteRefUpdate;
-import org.eclipse.jgit.transport.URIish;
-
-/**
- * Data class for storing push operation results for each remote repository/URI
- * being part of push operation.
- * <p>
- * One instance of this class is dedicated for result of one push operation:
- * either to one URI or to many URIs.
- *
- * @see PushOperation
- */
-public class PushOperationResult {
-	private LinkedHashMap<URIish, Entry> urisEntries;
-
-	/**
-	 * Construct empty push operation result.
-	 */
-	public PushOperationResult() {
-		this.urisEntries = new LinkedHashMap<URIish, Entry>();
-	}
-
-	/**
-	 * Add push result for the repository (URI) with successful connection.
-	 *
-	 * @param uri
-	 *            remote repository URI.
-	 * @param result
-	 *            push result.
-	 */
-	public void addOperationResult(final URIish uri, final PushResult result) {
-		urisEntries.put(uri, new Entry(result));
-	}
-
-	/**
-	 * Add error message for the repository (URI) with unsuccessful connection.
-	 *
-	 * @param uri
-	 *            remote repository URI.
-	 * @param errorMessage
-	 *            failure error message.
-	 */
-	public void addOperationResult(final URIish uri, final String errorMessage) {
-		urisEntries.put(uri, new Entry(errorMessage));
-	}
-
-	/**
-	 * @return set of remote repositories URIish. Set is ordered in addition
-	 *         sequence, which is usually the same as that from
-	 *         {@link PushOperationSpecification}.
-	 */
-	public Set<URIish> getURIs() {
-		return Collections.unmodifiableSet(urisEntries.keySet());
-	}
-
-	/**
-	 * @param uri
-	 *            remote repository URI.
-	 * @return true if connection was successful for this repository (URI),
-	 *         false if this operation ended with unsuccessful connection.
-	 */
-	public boolean isSuccessfulConnection(final URIish uri) {
-		return urisEntries.get(uri).isSuccessfulConnection();
-	}
-
-	/**
-	 * @return true if connection was successful for any repository (URI), false
-	 *         otherwise.
-	 */
-	public boolean isSuccessfulConnectionForAnyURI() {
-		for (final URIish uri : getURIs()) {
-			if (isSuccessfulConnection(uri))
-				return true;
-		}
-		return false;
-	}
-
-	/**
-	 * @param uri
-	 *            remote repository URI.
-	 * @return push result for this repository (URI) or null if operation ended
-	 *         with unsuccessful connection for this URI.
-	 */
-	public PushResult getPushResult(final URIish uri) {
-		return urisEntries.get(uri).getResult();
-	}
-
-	/**
-	 * @param uri
-	 *            remote repository URI.
-	 * @return error message for this repository (URI) or null if operation
-	 *         ended with successful connection for this URI.
-	 */
-	public String getErrorMessage(final URIish uri) {
-		return urisEntries.get(uri).getErrorMessage();
-	}
-
-	/**
-	 * @return string being list of failed URIs with their error messages.
-	 */
-	public String getErrorStringForAllURis() {
-		final StringBuilder sb = new StringBuilder();
-		boolean first = true;
-		for (final URIish uri : getURIs()) {
-			if (first)
-				first = false;
-			else
-				sb.append(", ");  //$NON-NLS-1$
-			sb.append(uri);
-			sb.append(" (");  //$NON-NLS-1$
-			sb.append(getErrorMessage(uri));
-			sb.append(")"); //$NON-NLS-1$
-		}
-		return sb.toString();
-	}
-
-	/**
-	 * Derive push operation specification from this push operation result.
-	 * <p>
-	 * Specification is created basing on URIs of remote repositories in this
-	 * result that completed without connection errors, and remote ref updates
-	 * from push results.
-	 * <p>
-	 * This method is targeted to provide support for 2-stage push, where first
-	 * operation is dry run for user confirmation and second one is a real
-	 * operation.
-	 *
-	 * @param requireUnchanged
-	 *            if true, newly created copies of remote ref updates have
-	 *            expected old object id set to previously advertised ref value
-	 *            (remote ref won't be updated if it change in the mean time),
-	 *            if false, newly create copies of remote ref updates have
-	 *            expected object id set up as in this result source
-	 *            specification.
-	 * @return derived specification for another push operation.
-	 * @throws IOException
-	 *             when some previously locally available source ref is not
-	 *             available anymore, or some error occurred during creation
-	 *             locally tracking ref update.
-	 *
-	 */
-	public PushOperationSpecification deriveSpecification(
-			final boolean requireUnchanged) throws IOException {
-		final PushOperationSpecification spec = new PushOperationSpecification();
-		for (final URIish uri : getURIs()) {
-			final PushResult pr = getPushResult(uri);
-			if (pr == null)
-				continue;
-
-			final Collection<RemoteRefUpdate> oldUpdates = pr
-					.getRemoteUpdates();
-			final ArrayList<RemoteRefUpdate> newUpdates = new ArrayList<RemoteRefUpdate>(
-					oldUpdates.size());
-			for (final RemoteRefUpdate rru : oldUpdates) {
-				final ObjectId expectedOldObjectId;
-				if (requireUnchanged) {
-					final Ref advertisedRef = getPushResult(uri)
-							.getAdvertisedRef(rru.getRemoteName());
-					if (advertisedRef == null)
-						expectedOldObjectId = ObjectId.zeroId();
-					else
-						expectedOldObjectId = advertisedRef.getObjectId();
-				} else
-					expectedOldObjectId = rru.getExpectedOldObjectId();
-				final RemoteRefUpdate newRru = new RemoteRefUpdate(rru,
-						expectedOldObjectId);
-				newUpdates.add(newRru);
-			}
-			spec.addURIRefUpdates(uri, newUpdates);
-		}
-		return spec;
-	}
-
-	/**
-	 * This implementation returns true if all following conditions are met:
-	 * <ul>
-	 * <li>both objects result have the same set successfully connected
-	 * repositories (URIs) - unsuccessful connections are discarded, AND <li>
-	 * remote ref updates must match for each successful connection in sense of
-	 * equal remoteName, equal status and equal newObjectId value.</li>
-	 * </ul>
-	 *
-	 * @see Object#equals(Object)
-	 * @param obj
-	 *            other push operation result to compare to.
-	 * @return true if object is equal to this one in terms of conditions
-	 *         described above, false otherwise.
-	 */
-	@Override
-	public boolean equals(final Object obj) {
-		if (obj == this)
-			return true;
-
-		if (!(obj instanceof PushOperationResult))
-			return false;
-
-		final PushOperationResult other = (PushOperationResult) obj;
-
-		// Check successful connections/URIs two-ways:
-		final Set<URIish> otherURIs = other.getURIs();
-		for (final URIish uri : getURIs()) {
-			if (isSuccessfulConnection(uri)
-					&& (!otherURIs.contains(uri) || !other
-							.isSuccessfulConnection(uri)))
-				return false;
-		}
-		for (final URIish uri : other.getURIs()) {
-			if (other.isSuccessfulConnection(uri)
-					&& (!urisEntries.containsKey(uri) || !isSuccessfulConnection(uri)))
-				return false;
-		}
-
-		for (final URIish uri : getURIs()) {
-			if (!isSuccessfulConnection(uri))
-				continue;
-
-			final PushResult otherPushResult = other.getPushResult(uri);
-			for (final RemoteRefUpdate rru : getPushResult(uri)
-					.getRemoteUpdates()) {
-				final RemoteRefUpdate otherRru = otherPushResult
-						.getRemoteUpdate(rru.getRemoteName());
-				if (otherRru == null)
-					return false;
-				if (otherRru.getStatus() != rru.getStatus()
-						|| otherRru.getNewObjectId() != rru.getNewObjectId())
-					return false;
-			}
-		}
-		return true;
-	}
-
-	@Override
-	public int hashCode() {
-		return urisEntries.hashCode();
-	}
-
-	private static class Entry {
-		private String errorMessage;
-
-		private PushResult result;
-
-		Entry(final PushResult result) {
-			this.result = result;
-		}
-
-		Entry(final String errorMessage) {
-			this.errorMessage = errorMessage;
-		}
-
-		boolean isSuccessfulConnection() {
-			return result != null;
-		}
-
-		String getErrorMessage() {
-			return errorMessage;
-		}
-
-		PushResult getResult() {
-			return result;
-		}
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/PushOperationSpecification.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/PushOperationSpecification.java
deleted file mode 100644
index 6369f5a..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/PushOperationSpecification.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.op;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.Set;
-
-import org.eclipse.jgit.transport.RemoteRefUpdate;
-import org.eclipse.jgit.transport.URIish;
-
-/**
- * Data class storing push operation update specifications for each remote
- * repository.
- * <p>
- * One instance is dedicated for one push operation: either push to one URI or
- * to many URIs.
- *
- * @see PushOperation
- */
-public class PushOperationSpecification {
-	private LinkedHashMap<URIish, Collection<RemoteRefUpdate>> urisRefUpdates;
-
-	/**
-	 * Create empty instance of specification.
-	 * <p>
-	 * URIs and ref updates should be configured
-	 * {@link #addURIRefUpdates(URIish, Collection)} method.
-	 */
-	public PushOperationSpecification() {
-		this.urisRefUpdates = new LinkedHashMap<URIish, Collection<RemoteRefUpdate>>();
-	}
-
-	/**
-	 * Add remote repository URI with ref updates specification.
-	 * <p>
-	 * Ref updates are not in constructor - pay attention to not share them
-	 * between different URIs ref updates or push operations.
-	 * <p>
-	 * Note that refUpdates can differ between URIs <b>only</b> by expected old
-	 * object id field: {@link RemoteRefUpdate#getExpectedOldObjectId()}.
-	 *
-	 * @param uri
-	 *            remote repository URI.
-	 * @param refUpdates
-	 *            collection of remote ref updates specifications.
-	 */
-	public void addURIRefUpdates(final URIish uri,
-			Collection<RemoteRefUpdate> refUpdates) {
-		urisRefUpdates.put(uri, refUpdates);
-	}
-
-	/**
-	 * @return set of remote repositories URIish. Set is ordered in addition
-	 *         sequence.
-	 */
-	public Set<URIish> getURIs() {
-		return Collections.unmodifiableSet(urisRefUpdates.keySet());
-	}
-
-	/**
-	 * @return number of remote repositories URI for this push operation.
-	 */
-	public int getURIsNumber() {
-		return urisRefUpdates.keySet().size();
-	}
-
-	/**
-	 * @param uri
-	 *            remote repository URI.
-	 * @return remote ref updates as specified by user for this URI.
-	 */
-	public Collection<RemoteRefUpdate> getRefUpdates(final URIish uri) {
-		return Collections.unmodifiableCollection(urisRefUpdates.get(uri));
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/RebaseOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/RebaseOperation.java
deleted file mode 100644
index 35f45da..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/RebaseOperation.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010 SAP AG.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *    Mathias Kinzler <mathias.kinzler@sap.com> - initial implementation
- *******************************************************************************/
-package org.eclipse.egit.core.op;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IWorkspaceRunnable;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.core.runtime.jobs.ISchedulingRule;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.CoreText;
-import org.eclipse.egit.core.EclipseGitProgressTransformer;
-import org.eclipse.egit.core.internal.util.ProjectUtil;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.api.RebaseCommand;
-import org.eclipse.jgit.api.RebaseResult;
-import org.eclipse.jgit.api.RebaseCommand.Operation;
-import org.eclipse.jgit.api.errors.GitAPIException;
-import org.eclipse.jgit.api.errors.JGitInternalException;
-import org.eclipse.jgit.api.errors.NoHeadException;
-import org.eclipse.jgit.api.errors.RefNotFoundException;
-import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.lib.Repository;
-
-/**
- * This class implements rebase.
- */
-public class RebaseOperation implements IEGitOperation {
-	private final Repository repository;
-
-	private final Ref ref;
-
-	private final Operation operation;
-
-	private RebaseResult result;
-
-	/**
-	 * Construct a {@link RebaseOperation} object for a {@link Ref}.
-	 * <p>
-	 * Upon {@link #execute(IProgressMonitor)}, the current HEAD will be rebased
-	 * onto the provided {@link Ref}
-	 *
-	 * @param repository
-	 *            the {@link Repository}
-	 * @param ref
-	 *            the branch or tag
-	 */
-	public RebaseOperation(Repository repository, Ref ref) {
-		this.repository = repository;
-		this.operation = Operation.BEGIN;
-		this.ref = ref;
-	}
-
-	/**
-	 * Used to abort, skip, or continue a stopped rebase operation that has been
-	 * started before.
-	 *
-	 * @param repository
-	 *            the {@link Repository}
-	 * @param operation
-	 *            one of {@link Operation#ABORT}, {@link Operation#CONTINUE},
-	 *            {@link Operation#SKIP}
-	 */
-	public RebaseOperation(Repository repository, Operation operation) {
-		this.repository = repository;
-		this.operation = operation;
-		this.ref = null;
-	}
-
-	public void execute(IProgressMonitor m) throws CoreException {
-		if (result != null)
-			throw new CoreException(new Status(IStatus.ERROR, Activator
-					.getPluginId(), CoreText.OperationAlreadyExecuted));
-		IProgressMonitor monitor;
-		if (m == null)
-			monitor = new NullProgressMonitor();
-		else
-			monitor = m;
-		final IProject[] validProjects = ProjectUtil.getValidOpenProjects(repository);
-		IWorkspaceRunnable action = new IWorkspaceRunnable() {
-			public void run(IProgressMonitor actMonitor) throws CoreException {
-				RebaseCommand cmd = new Git(repository).rebase()
-						.setProgressMonitor(
-								new EclipseGitProgressTransformer(actMonitor));
-				try {
-					if (operation == Operation.BEGIN)
-						result = cmd.setUpstream(ref.getName()).call();
-					else
-						result = cmd.setOperation(operation).call();
-
-				} catch (NoHeadException e) {
-					throw new CoreException(Activator.error(e.getMessage(), e));
-				} catch (RefNotFoundException e) {
-					throw new CoreException(Activator.error(e.getMessage(), e));
-				} catch (JGitInternalException e) {
-					throw new CoreException(Activator.error(e.getMessage(), e));
-				} catch (GitAPIException e) {
-					throw new CoreException(Activator.error(e.getMessage(), e));
-				} finally {
-					if (refreshNeeded())
-						ProjectUtil.refreshValidProjects(validProjects,
-								new SubProgressMonitor(actMonitor, 1));
-				}
-			}
-		};
-		ResourcesPlugin.getWorkspace().run(action, monitor);
-	}
-
-	private boolean refreshNeeded() {
-		if (result == null)
-			return true;
-		if (result.getStatus() == RebaseResult.Status.UP_TO_DATE)
-			return false;
-		return true;
-	}
-
-	public ISchedulingRule getSchedulingRule() {
-		return ResourcesPlugin.getWorkspace().getRoot();
-	}
-
-	/**
-	 * @return the result of calling {@link #execute(IProgressMonitor)}, or
-	 *         <code>null</code> if this has not been executed yet
-	 */
-	public RebaseResult getResult() {
-		return result;
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/RemoveFromIndexOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/RemoveFromIndexOperation.java
deleted file mode 100644
index 5cac22f..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/RemoveFromIndexOperation.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2011, Bernard Leach <leachbj@bouncycastle.org>
- * Copyright (C) 2011, Dariusz Luksza <dariusz@luksza.org>
- * Copyright (C) 2012, Robin Stocker <robin@nibor.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.op;
-
-import static org.eclipse.egit.core.project.RepositoryMapping.findRepositoryMapping;
-import static org.eclipse.jgit.lib.Constants.HEAD;
-
-import java.io.IOException;
-import java.util.Collection;
-import java.util.Map;
-
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.jobs.ISchedulingRule;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.CoreText;
-import org.eclipse.egit.core.internal.job.RuleUtil;
-import org.eclipse.egit.core.internal.util.ResourceUtil;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.api.GitCommand;
-import org.eclipse.jgit.api.ResetCommand;
-import org.eclipse.jgit.api.RmCommand;
-import org.eclipse.jgit.api.errors.GitAPIException;
-import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.lib.Repository;
-
-/**
- * Remove from Git Index operation (unstage).
- */
-public class RemoveFromIndexOperation implements IEGitOperation {
-
-	private final Map<Repository, Collection<String>> pathsByRepository;
-
-	/**
-	 * @param paths
-	 *            list of paths that should be removed from index
-	 * @since 2.2
-	 */
-	public RemoveFromIndexOperation(Collection<IPath> paths) {
-		this.pathsByRepository = ResourceUtil.splitPathsByRepository(paths);
-	}
-
-	/**
-	 * @param repo
-	 *            repository in with given files should be removed from index
-	 * @param resources
-	 *            list of resources that should be removed from index
-	 * @deprecated use {@link #RemoveFromIndexOperation(Collection)} instead
-	 */
-	@Deprecated
-	public RemoveFromIndexOperation(Repository repo, IResource[] resources) {
-		this.pathsByRepository = ResourceUtil.splitResourcesByRepository(resources);
-	}
-
-	public void execute(IProgressMonitor m) throws CoreException {
-		IProgressMonitor monitor = (m != null) ? m : new NullProgressMonitor();
-
-		monitor.beginTask(
-				CoreText.RemoveFromIndexOperation_removingFilesFromIndex,
-				pathsByRepository.size());
-
-		for (Map.Entry<Repository, Collection<String>> entry : pathsByRepository.entrySet()) {
-			Repository repository = entry.getKey();
-			Collection<String> paths = entry.getValue();
-
-			GitCommand<?> command = prepareCommand(repository, paths);
-
-			try {
-				command.call();
-				monitor.worked(1);
-			} catch (GitAPIException e) {
-				Activator.logError(e.getMessage(), e);
-			} finally {
-				findRepositoryMapping(repository).fireRepositoryChanged();
-			}
-		}
-
-		monitor.done();
-	}
-
-	public ISchedulingRule getSchedulingRule() {
-		return RuleUtil.getRuleForRepositories(pathsByRepository.keySet());
-	}
-
-	private static GitCommand<?> prepareCommand(Repository repository,
-			Collection<String> paths) {
-		Git git = new Git(repository);
-		if (hasHead(repository)) {
-			ResetCommand resetCommand = git.reset();
-			resetCommand.setRef(HEAD);
-			for (String path : paths)
-				resetCommand.addPath(getCommandPath(path));
-			return resetCommand;
-		} else {
-			RmCommand rmCommand = git.rm();
-			rmCommand.setCached(true);
-			for (String path : paths)
-				rmCommand.addFilepattern(getCommandPath(path));
-			return rmCommand;
-		}
-	}
-
-	private static boolean hasHead(Repository repository) {
-		try {
-			Ref head = repository.getRef(HEAD);
-			return head != null && head.getObjectId() != null;
-		} catch (IOException e) {
-			return false;
-		}
-	}
-
-	private static String getCommandPath(String path) {
-		if ("".equals(path)) // Working directory //$NON-NLS-1$
-			return "."; //$NON-NLS-1$
-		else
-			return path;
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/RenameBranchOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/RenameBranchOperation.java
deleted file mode 100644
index f55b43f..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/RenameBranchOperation.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2010, Mathias Kinzler <mathias.kinzler@sap.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.op;
-
-import org.eclipse.core.resources.IWorkspaceRunnable;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.jobs.ISchedulingRule;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.CoreText;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.api.errors.GitAPIException;
-import org.eclipse.jgit.api.errors.JGitInternalException;
-import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.osgi.util.NLS;
-
-/**
- * This class implements renaming of a branch
- */
-public class RenameBranchOperation implements IEGitOperation {
-	private final Repository repository;
-
-	private final Ref branch;
-
-	private final String newName;
-
-	/**
-	 * @param repository
-	 * @param branch
-	 *            the branch to rename
-	 * @param newName
-	 *            the new name
-	 */
-	public RenameBranchOperation(Repository repository, Ref branch,
-			String newName) {
-		this.repository = repository;
-		this.branch = branch;
-		this.newName = newName;
-	}
-
-	public void execute(IProgressMonitor m) throws CoreException {
-		IProgressMonitor monitor;
-		if (m == null)
-			monitor = new NullProgressMonitor();
-		else
-			monitor = m;
-
-		IWorkspaceRunnable action = new IWorkspaceRunnable() {
-			public void run(IProgressMonitor actMonitor) throws CoreException {
-				String taskName = NLS.bind(
-						CoreText.RenameBranchOperation_TaskName, branch
-								.getName(), newName);
-				actMonitor.beginTask(taskName, 1);
-				try {
-					new Git(repository).branchRename().setOldName(
-							branch.getName()).setNewName(newName).call();
-				} catch (JGitInternalException e) {
-					throw new CoreException(Activator.error(e.getMessage(), e));
-				} catch (GitAPIException e) {
-					throw new CoreException(Activator.error(e.getMessage(), e));
-				}
-				actMonitor.worked(1);
-				actMonitor.done();
-			}
-		};
-		// lock workspace to protect working tree changes
-		ResourcesPlugin.getWorkspace().run(action, monitor);
-	}
-
-	public ISchedulingRule getSchedulingRule() {
-		return ResourcesPlugin.getWorkspace().getRoot();
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/ResetOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/ResetOperation.java
deleted file mode 100644
index 6693f22..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/ResetOperation.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2007, Dave Watson <dwatson@mimvista.com>
- * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * Copyright (C) 2010, Mathias Kinzler <mathias.kinzler@sap.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.op;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IWorkspaceRunnable;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.core.runtime.jobs.ISchedulingRule;
-import org.eclipse.egit.core.CoreText;
-import org.eclipse.egit.core.internal.util.ProjectUtil;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.api.ResetCommand;
-import org.eclipse.jgit.api.ResetCommand.ResetType;
-import org.eclipse.jgit.api.errors.GitAPIException;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.osgi.util.NLS;
-import org.eclipse.team.core.TeamException;
-
-/**
- * A class for changing a ref and possibly index and workdir too.
- */
-public class ResetOperation implements IEGitOperation {
-
-	private final Repository repository;
-
-	private final String refName;
-
-	private final ResetType type;
-
-	/**
-	 * Construct a {@link ResetOperation}
-	 *
-	 * @param repository
-	 * @param refName
-	 * @param type
-	 */
-	public ResetOperation(Repository repository, String refName, ResetType type) {
-		this.repository = repository;
-		this.refName = refName;
-		this.type = type;
-	}
-
-	public ISchedulingRule getSchedulingRule() {
-		if (type == ResetType.HARD)
-			return ResourcesPlugin.getWorkspace().getRoot();
-		else
-			return null;
-	}
-
-	public void execute(IProgressMonitor m) throws CoreException {
-		IProgressMonitor monitor;
-		if (m == null)
-			monitor = new NullProgressMonitor();
-		else
-			monitor = m;
-		if (type == ResetType.HARD) {
-			IWorkspaceRunnable action = new IWorkspaceRunnable() {
-				public void run(IProgressMonitor actMonitor) throws CoreException {
-					reset(actMonitor);
-				}
-			};
-			// lock workspace to protect working tree changes
-			ResourcesPlugin.getWorkspace().run(action, monitor);
-		} else {
-			reset(monitor);
-		}
-	}
-
-	private void reset(IProgressMonitor monitor) throws CoreException {
-		monitor.beginTask(NLS.bind(CoreText.ResetOperation_performingReset,
-				type.toString().toLowerCase(), refName), 2);
-
-		IProject[] validProjects = null;
-		if (type == ResetType.HARD)
-			validProjects = ProjectUtil.getValidOpenProjects(repository);
-
-		ResetCommand reset = Git.wrap(repository).reset();
-		reset.setMode(type);
-		reset.setRef(refName);
-		try {
-			reset.call();
-		} catch (GitAPIException e) {
-			throw new TeamException(e.getLocalizedMessage(), e.getCause());
-		}
-		monitor.worked(1);
-
-		// only refresh if working tree changes
-		if (type == ResetType.HARD)
-			ProjectUtil.refreshValidProjects(validProjects,
-					new SubProgressMonitor(monitor, 1));
-
-		monitor.done();
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/RevertCommitOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/RevertCommitOperation.java
deleted file mode 100644
index c1d347f..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/RevertCommitOperation.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/******************************************************************************
- *  Copyright (c) 2011 GitHub Inc.
- *  All rights reserved. This program and the accompanying materials
- *  are made available under the terms of the Eclipse Public License v1.0
- *  which accompanies this distribution, and is available at
- *  http://www.eclipse.org/legal/epl-v10.html
- *
- *  Contributors:
- *    Kevin Sawicki (GitHub Inc.) - initial API and implementation
- *****************************************************************************/
-package org.eclipse.egit.core.op;
-
-import java.text.MessageFormat;
-import java.util.List;
-
-import org.eclipse.core.resources.IWorkspaceRunnable;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.core.runtime.jobs.ISchedulingRule;
-import org.eclipse.egit.core.CoreText;
-import org.eclipse.egit.core.internal.util.ProjectUtil;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.api.MergeResult;
-import org.eclipse.jgit.api.RevertCommand;
-import org.eclipse.jgit.api.errors.GitAPIException;
-import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.team.core.TeamException;
-
-/**
- * Operation to revert a commit
- */
-public class RevertCommitOperation implements IEGitOperation {
-
-	private final Repository repo;
-
-	private final RevCommit commit;
-
-	private RevCommit newHead;
-
-	private List<Ref> reverted;
-
-	private MergeResult result;
-
-	/**
-	 * Create revert commit operation
-	 *
-	 * @param repository
-	 * @param commit
-	 */
-	public RevertCommitOperation(Repository repository, RevCommit commit) {
-		this.repo = repository;
-		this.commit = commit;
-	}
-
-	/**
-	 * @return new head commit
-	 */
-	public RevCommit getNewHead() {
-		return newHead;
-	}
-
-	/**
-	 * @return reverted refs
-	 */
-	public List<Ref> getRevertedRefs() {
-		return reverted;
-	}
-
-	public void execute(IProgressMonitor m) throws CoreException {
-		IProgressMonitor monitor = m != null ? m : new NullProgressMonitor();
-		IWorkspaceRunnable action = new IWorkspaceRunnable() {
-
-			public void run(IProgressMonitor pm) throws CoreException {
-				pm.beginTask("", 2); //$NON-NLS-1$
-
-				pm.subTask(MessageFormat.format(
-						CoreText.RevertCommitOperation_reverting, commit.name()));
-				RevertCommand command = new Git(repo).revert().include(commit);
-				try {
-					newHead = command.call();
-					reverted = command.getRevertedRefs();
-					result = command.getFailingResult();
-				} catch (GitAPIException e) {
-					throw new TeamException(e.getLocalizedMessage(),
-							e.getCause());
-				}
-				pm.worked(1);
-
-				ProjectUtil.refreshValidProjects(
-						ProjectUtil.getValidOpenProjects(repo),
-						new SubProgressMonitor(pm, 1));
-
-				pm.done();
-			}
-		};
-		ResourcesPlugin.getWorkspace().run(action, monitor);
-	}
-
-	public ISchedulingRule getSchedulingRule() {
-		return ResourcesPlugin.getWorkspace().getRoot();
-	}
-
-	/**
-	 * Get failing result of merge
-	 *
-	 * @return merge result
-	 */
-	public MergeResult getFailingResult() {
-		return result;
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/SetChangeIdTask.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/SetChangeIdTask.java
deleted file mode 100644
index 0cf1b70..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/SetChangeIdTask.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2011, Stefan Lay <stefan.lay@sap.com>
- * Copyright (C) 2011, Matthias Sohn <matthias.sohn@sap.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.op;
-
-import java.io.IOException;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.op.CloneOperation.PostCloneTask;
-import org.eclipse.jgit.lib.ConfigConstants;
-import org.eclipse.jgit.lib.Repository;
-
-/**
- * Sets the config property gerrit.createchangeid
- */
-public class SetChangeIdTask implements PostCloneTask {
-
-	private final boolean createchangeid;
-
-	/**
-	 * @param createchangeid
-	 */
-	public SetChangeIdTask(boolean createchangeid) {
-		this.createchangeid = createchangeid;
-	}
-
-	public void execute(Repository repository, IProgressMonitor monitor)
-			throws CoreException {
-		try {
-			repository.getConfig().setBoolean(ConfigConstants.CONFIG_GERRIT_SECTION,
-					null, ConfigConstants.CONFIG_KEY_CREATECHANGEID, createchangeid);
-			repository.getConfig().save();
-		} catch (IOException e) {
-			throw new CoreException(Activator.error(e.getMessage(), e));
-		}
-	}
-
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/SetRepositoryConfigPropertyTask.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/SetRepositoryConfigPropertyTask.java
deleted file mode 100644
index 04c45bd..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/SetRepositoryConfigPropertyTask.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2012, Stefan Lay <stefan.lay@sap.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.op;
-
-import java.io.IOException;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.op.CloneOperation.PostCloneTask;
-import org.eclipse.jgit.lib.Repository;
-
-/**
- * Sets config properties for a repository
- */
-public class SetRepositoryConfigPropertyTask implements PostCloneTask {
-
-	private final String section;
-	private final String subsection;
-	private final String name;
-	private final String value;
-
-	/**
-	 * @param section
-	 * @param subsection
-	 * @param name
-	 * @param value
-	 */
-	public SetRepositoryConfigPropertyTask(String section, String subsection, String name, String value) {
-		this.section = section;
-		this.subsection = subsection;
-		this.name = name;
-		this.value = value;
-	}
-
-	public void execute(Repository repository, IProgressMonitor monitor)
-			throws CoreException {
-		try {
-			repository.getConfig().setString(section, subsection, name, value);
-			repository.getConfig().save();
-		} catch (IOException e) {
-			throw new CoreException(Activator.error(e.getMessage(), e));
-		}
-	}
-
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/StashApplyOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/StashApplyOperation.java
deleted file mode 100644
index 41e5dde..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/StashApplyOperation.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/******************************************************************************
- *  Copyright (c) 2012 GitHub Inc.
- *  All rights reserved. This program and the accompanying materials
- *  are made available under the terms of the Eclipse Public License v1.0
- *  which accompanies this distribution, and is available at
- *  http://www.eclipse.org/legal/epl-v10.html
- *
- *  Contributors:
- *    Kevin Sawicki (GitHub Inc.) - initial API and implementation
- *****************************************************************************/
-package org.eclipse.egit.core.op;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IWorkspaceRunnable;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.core.runtime.jobs.ISchedulingRule;
-import org.eclipse.egit.core.internal.util.ProjectUtil;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.api.errors.GitAPIException;
-import org.eclipse.jgit.api.errors.JGitInternalException;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.team.core.TeamException;
-
-/**
- * Operation that applies a stashed commit in a repository
- */
-public class StashApplyOperation implements IEGitOperation {
-
-	private final Repository repository;
-
-	private final RevCommit commit;
-
-	/**
-	 * Create operation for repository
-	 *
-	 * @param repository
-	 * @param commit
-	 */
-	public StashApplyOperation(final Repository repository,
-			final RevCommit commit) {
-		this.repository = repository;
-		this.commit = commit;
-	}
-
-	public void execute(IProgressMonitor monitor) throws CoreException {
-		IWorkspaceRunnable action = new IWorkspaceRunnable() {
-
-			public void run(IProgressMonitor pm) throws CoreException {
-				pm.beginTask("", 3); //$NON-NLS-1$
-				try {
-					IProject[] validProjects = ProjectUtil
-							.getValidOpenProjects(repository);
-					pm.worked(1);
-					Git.wrap(repository).stashApply()
-							.setStashRef(commit.name()).call();
-					pm.worked(1);
-					ProjectUtil.refreshValidProjects(validProjects,
-							new SubProgressMonitor(pm, 1));
-				} catch (JGitInternalException e) {
-					throw new TeamException(e.getLocalizedMessage(),
-							e.getCause());
-				} catch (GitAPIException e) {
-					throw new TeamException(e.getLocalizedMessage(),
-							e.getCause());
-				} finally {
-					pm.done();
-				}
-			}
-		};
-		ResourcesPlugin.getWorkspace().run(action,
-				monitor != null ? monitor : new NullProgressMonitor());
-	}
-
-	public ISchedulingRule getSchedulingRule() {
-		return ResourcesPlugin.getWorkspace().getRoot();
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/StashCreateOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/StashCreateOperation.java
deleted file mode 100644
index d278d1b..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/StashCreateOperation.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/******************************************************************************
- *  Copyright (c) 2012 GitHub Inc.
- *  All rights reserved. This program and the accompanying materials
- *  are made available under the terms of the Eclipse Public License v1.0
- *  which accompanies this distribution, and is available at
- *  http://www.eclipse.org/legal/epl-v10.html
- *
- *  Contributors:
- *    Kevin Sawicki (GitHub Inc.) - initial API and implementation
- *****************************************************************************/
-package org.eclipse.egit.core.op;
-
-import org.eclipse.core.resources.IWorkspaceRunnable;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.jobs.ISchedulingRule;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.api.StashCreateCommand;
-import org.eclipse.jgit.api.errors.GitAPIException;
-import org.eclipse.jgit.api.errors.JGitInternalException;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.team.core.TeamException;
-
-/**
- * Operation that creates a stashed commit for a repository
- */
-public class StashCreateOperation implements IEGitOperation {
-
-	private final Repository repository;
-
-	private final String message;
-
-	private RevCommit commit;
-
-	/**
-	 * Create operation for repository
-	 *
-	 * @param repository
-	 */
-	public StashCreateOperation(final Repository repository) {
-		this(repository, null);
-	}
-
-	/**
-	 * Create operation for repository
-	 *
-	 * @param repository
-	 * @param message
-	 */
-	public StashCreateOperation(final Repository repository, final String message) {
-		this.repository = repository;
-		this.message = message;
-	}
-
-	/**
-	 * Get stashed commit
-	 *
-	 * @return commit
-	 */
-	public RevCommit getCommit() {
-		return commit;
-	}
-
-	public void execute(IProgressMonitor monitor) throws CoreException {
-		IWorkspaceRunnable action = new IWorkspaceRunnable() {
-
-			public void run(IProgressMonitor pm) throws CoreException {
-				try {
-					StashCreateCommand command = Git.wrap(repository).stashCreate();
-					if (message != null) {
-						command.setIndexMessage(message);
-						command.setWorkingDirectoryMessage(message);
-					}
-					commit = command.call();
-				} catch (JGitInternalException e) {
-					throw new TeamException(e.getLocalizedMessage(),
-							e.getCause());
-				} catch (GitAPIException e) {
-					throw new TeamException(e.getLocalizedMessage(),
-							e.getCause());
-				} finally {
-					if (commit != null)
-						repository.notifyIndexChanged();
-					pm.done();
-				}
-			}
-		};
-		ResourcesPlugin.getWorkspace().run(action,
-				monitor != null ? monitor : new NullProgressMonitor());
-	}
-
-	public ISchedulingRule getSchedulingRule() {
-		return ResourcesPlugin.getWorkspace().getRoot();
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/StashDropOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/StashDropOperation.java
deleted file mode 100644
index d443a0b..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/StashDropOperation.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/******************************************************************************
- *  Copyright (c) 2012 GitHub Inc.
- *  All rights reserved. This program and the accompanying materials
- *  are made available under the terms of the Eclipse Public License v1.0
- *  which accompanies this distribution, and is available at
- *  http://www.eclipse.org/legal/epl-v10.html
- *
- *  Contributors:
- *    Kevin Sawicki (GitHub Inc.) - initial API and implementation
- *****************************************************************************/
-package org.eclipse.egit.core.op;
-
-import org.eclipse.core.resources.IWorkspaceRunnable;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.jobs.ISchedulingRule;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.api.StashDropCommand;
-import org.eclipse.jgit.api.errors.GitAPIException;
-import org.eclipse.jgit.api.errors.JGitInternalException;
-import org.eclipse.jgit.events.RefsChangedEvent;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.team.core.TeamException;
-
-/**
- * Operation to drop a stashed commit
- */
-public class StashDropOperation implements IEGitOperation {
-
-	private final int index;
-
-	private final Repository repo;
-
-	/**
-	 * Create an operation to drop the stashed commit with the given index
-	 *
-	 * @param repo
-	 * @param index
-	 */
-	public StashDropOperation(final Repository repo, final int index) {
-		if (index < 0)
-			throw new IllegalArgumentException();
-		this.index = index;
-		this.repo = repo;
-	}
-
-	public void execute(IProgressMonitor monitor) throws CoreException {
-		IWorkspaceRunnable action = new IWorkspaceRunnable() {
-
-			public void run(IProgressMonitor pm) throws CoreException {
-				pm.beginTask("", 1); //$NON-NLS-1$
-				StashDropCommand command = Git.wrap(repo).stashDrop();
-				command.setStashRef(index);
-				try {
-					command.call();
-					repo.fireEvent(new RefsChangedEvent());
-				} catch (JGitInternalException e) {
-					throw new TeamException(e.getLocalizedMessage(),
-							e.getCause());
-				} catch (GitAPIException e) {
-					throw new TeamException(e.getLocalizedMessage(),
-							e.getCause());
-				} finally {
-					pm.done();
-				}
-			}
-		};
-		ResourcesPlugin.getWorkspace().run(action,
-				monitor != null ? monitor : new NullProgressMonitor());
-	}
-
-	public ISchedulingRule getSchedulingRule() {
-		return ResourcesPlugin.getWorkspace().getRoot();
-	}
-
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/SubmoduleAddOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/SubmoduleAddOperation.java
deleted file mode 100644
index 5d1860d..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/SubmoduleAddOperation.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/******************************************************************************
- *  Copyright (c) 2012 GitHub Inc.
- *  All rights reserved. This program and the accompanying materials
- *  are made available under the terms of the Eclipse Public License v1.0
- *  which accompanies this distribution, and is available at
- *  http://www.eclipse.org/legal/epl-v10.html
- *
- *  Contributors:
- *    Kevin Sawicki (GitHub Inc.) - initial API and implementation
- *****************************************************************************/
-package org.eclipse.egit.core.op;
-
-import org.eclipse.core.resources.IWorkspaceRunnable;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.jobs.ISchedulingRule;
-import org.eclipse.egit.core.EclipseGitProgressTransformer;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.api.SubmoduleAddCommand;
-import org.eclipse.jgit.api.errors.GitAPIException;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.team.core.TeamException;
-
-/**
- * Operation to add a submodule to a repository
- */
-public class SubmoduleAddOperation implements IEGitOperation {
-
-	private final Repository repo;
-
-	private final String path;
-
-	private final String uri;
-
-	/**
-	 * Create operation
-	 *
-	 * @param repo
-	 * @param path
-	 * @param uri
-	 */
-	public SubmoduleAddOperation(final Repository repo, final String path,
-			final String uri) {
-		this.repo = repo;
-		this.path = path;
-		this.uri = uri;
-	}
-
-	public void execute(IProgressMonitor monitor) throws CoreException {
-		IWorkspaceRunnable action = new IWorkspaceRunnable() {
-
-			public void run(IProgressMonitor pm) throws CoreException {
-				final SubmoduleAddCommand add = Git.wrap(repo).submoduleAdd();
-				add.setProgressMonitor(new EclipseGitProgressTransformer(pm));
-				add.setPath(path);
-				add.setURI(uri);
-				try {
-					if (add.call() != null)
-						repo.notifyIndexChanged();
-				} catch (GitAPIException e) {
-					throw new TeamException(e.getLocalizedMessage(),
-							e.getCause());
-				}
-			}
-		};
-		ResourcesPlugin.getWorkspace().run(action,
-				monitor != null ? monitor : new NullProgressMonitor());
-	}
-
-	public ISchedulingRule getSchedulingRule() {
-		return ResourcesPlugin.getWorkspace().getRoot();
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/SubmoduleSyncOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/SubmoduleSyncOperation.java
deleted file mode 100644
index d2108fd..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/SubmoduleSyncOperation.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/******************************************************************************
- *  Copyright (c) 2012 GitHub Inc.
- *  All rights reserved. This program and the accompanying materials
- *  are made available under the terms of the Eclipse Public License v1.0
- *  which accompanies this distribution, and is available at
- *  http://www.eclipse.org/legal/epl-v10.html
- *
- *  Contributors:
- *    Kevin Sawicki (GitHub Inc.) - initial API and implementation
- *****************************************************************************/
-package org.eclipse.egit.core.op;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Map;
-
-import org.eclipse.core.resources.IWorkspaceRunnable;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.jobs.ISchedulingRule;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.api.SubmoduleSyncCommand;
-import org.eclipse.jgit.api.errors.GitAPIException;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.team.core.TeamException;
-
-/**
- * Operation that syncs a repository's submodule configurations
- */
-public class SubmoduleSyncOperation implements IEGitOperation {
-
-	private final Repository repository;
-
-	private final Collection<String> paths;
-
-	/**
-	 * Create submodule sync operation
-	 *
-	 * @param repository
-	 */
-	public SubmoduleSyncOperation(final Repository repository) {
-		this.repository = repository;
-		paths = new ArrayList<String>();
-	}
-
-	/**
-	 * Add path of submodule to update
-	 *
-	 * @param path
-	 * @return this operation
-	 */
-	public SubmoduleSyncOperation addPath(final String path) {
-		paths.add(path);
-		return this;
-	}
-
-	public void execute(final IProgressMonitor monitor) throws CoreException {
-		IWorkspaceRunnable action = new IWorkspaceRunnable() {
-
-			public void run(IProgressMonitor pm) throws CoreException {
-				pm.beginTask("", 1); //$NON-NLS-1$
-				Map<String, String> updates = null;
-				try {
-					SubmoduleSyncCommand sync = Git.wrap(repository)
-							.submoduleSync();
-					for (String path : paths)
-						sync.addPath(path);
-					updates = sync.call();
-				} catch (GitAPIException e) {
-					throw new TeamException(e.getLocalizedMessage(),
-							e.getCause());
-				} finally {
-					if (updates != null && !updates.isEmpty())
-						repository.notifyIndexChanged();
-					pm.done();
-				}
-			}
-		};
-		ResourcesPlugin.getWorkspace().run(action,
-				monitor != null ? monitor : new NullProgressMonitor());
-	}
-
-	public ISchedulingRule getSchedulingRule() {
-		return null;
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/SubmoduleUpdateOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/SubmoduleUpdateOperation.java
deleted file mode 100644
index 724ffc0..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/SubmoduleUpdateOperation.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/******************************************************************************
- *  Copyright (c) 2012 GitHub Inc.
- *  All rights reserved. This program and the accompanying materials
- *  are made available under the terms of the Eclipse Public License v1.0
- *  which accompanies this distribution, and is available at
- *  http://www.eclipse.org/legal/epl-v10.html
- *
- *  Contributors:
- *    Kevin Sawicki (GitHub Inc.) - initial API and implementation
- *****************************************************************************/
-package org.eclipse.egit.core.op;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-
-import org.eclipse.core.resources.IWorkspaceRunnable;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.core.runtime.jobs.ISchedulingRule;
-import org.eclipse.egit.core.EclipseGitProgressTransformer;
-import org.eclipse.egit.core.internal.util.ProjectUtil;
-import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.api.SubmoduleInitCommand;
-import org.eclipse.jgit.api.SubmoduleUpdateCommand;
-import org.eclipse.jgit.api.errors.GitAPIException;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.submodule.SubmoduleWalk;
-import org.eclipse.team.core.TeamException;
-
-/**
- * Operation that updates a repository's submodules
- */
-public class SubmoduleUpdateOperation implements IEGitOperation {
-
-	private final Repository repository;
-
-	private final Collection<String> paths;
-
-	/**
-	 * Create submodule update operation
-	 *
-	 * @param repository
-	 */
-	public SubmoduleUpdateOperation(final Repository repository) {
-		this.repository = repository;
-		paths = new ArrayList<String>();
-	}
-
-	/**
-	 * Add path of submodule to update
-	 *
-	 * @param path
-	 * @return this operation
-	 */
-	public SubmoduleUpdateOperation addPath(final String path) {
-		paths.add(path);
-		return this;
-	}
-
-	public void execute(final IProgressMonitor monitor) throws CoreException {
-		IWorkspaceRunnable action = new IWorkspaceRunnable() {
-
-			public void run(IProgressMonitor pm) throws CoreException {
-				pm.beginTask("", 3); //$NON-NLS-1$
-				Git git = Git.wrap(repository);
-
-				Collection<String> updated = null;
-				try {
-					SubmoduleInitCommand init = git.submoduleInit();
-					for (String path : paths)
-						init.addPath(path);
-					init.call();
-					pm.worked(1);
-
-					SubmoduleUpdateCommand update = git.submoduleUpdate();
-					for (String path : paths)
-						update.addPath(path);
-					update.setProgressMonitor(new EclipseGitProgressTransformer(
-							new SubProgressMonitor(pm, 2)));
-					updated = update.call();
-					pm.worked(1);
-					SubProgressMonitor refreshMonitor = new SubProgressMonitor(
-							pm, 1);
-					refreshMonitor.beginTask("", updated.size()); //$NON-NLS-1$
-					for (String path : updated) {
-						Repository subRepo = SubmoduleWalk
-								.getSubmoduleRepository(repository, path);
-						if (subRepo != null)
-							ProjectUtil.refreshValidProjects(
-									ProjectUtil.getValidOpenProjects(subRepo),
-									new SubProgressMonitor(refreshMonitor, 1));
-						else
-							refreshMonitor.worked(1);
-					}
-					refreshMonitor.done();
-				} catch (GitAPIException e) {
-					throw new TeamException(e.getLocalizedMessage(),
-							e.getCause());
-				} catch (IOException e) {
-					throw new TeamException(e.getLocalizedMessage(),
-							e.getCause());
-				} finally {
-					if (updated != null && !updated.isEmpty())
-						repository.notifyIndexChanged();
-					pm.done();
-				}
-			}
-		};
-		ResourcesPlugin.getWorkspace().run(action,
-				monitor != null ? monitor : new NullProgressMonitor());
-	}
-
-	public ISchedulingRule getSchedulingRule() {
-		return ResourcesPlugin.getWorkspace().getRoot();
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/TagOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/TagOperation.java
deleted file mode 100644
index d20ef3c..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/TagOperation.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.op;
-
-import java.io.IOException;
-
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.jobs.ISchedulingRule;
-import org.eclipse.egit.core.CoreText;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.ObjectInserter;
-import org.eclipse.jgit.lib.RefUpdate;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.lib.TagBuilder;
-import org.eclipse.jgit.lib.RefUpdate.Result;
-import org.eclipse.osgi.util.NLS;
-import org.eclipse.team.core.TeamException;
-
-/**
- * Tags repository with given {@link TagBuilder} object.
- */
-public class TagOperation implements IEGitOperation {
-
-	private final TagBuilder tag;
-	private final Repository repo;
-	private final boolean shouldMoveTag;
-
-	/**
-	 * Construct TagOperation
-	 *
-	 * @param repo
-	 * @param tag
-	 * @param shouldMoveTag if <code>true</code> it will replace tag with same name
-	 */
-	public TagOperation(Repository repo, TagBuilder tag, boolean shouldMoveTag) {
-		this.tag = tag;
-		this.repo = repo;
-		this.shouldMoveTag = shouldMoveTag;
-	}
-
-
-	public void execute(IProgressMonitor m) throws CoreException {
-		IProgressMonitor monitor;
-		if (m == null)
-			monitor = new NullProgressMonitor();
-		else
-			monitor = m;
-		try {
-			monitor.beginTask(NLS.bind(CoreText.TagOperation_performingTagging,
-					tag.getTag()), 3);
-
-			ObjectId tagId = updateTagObject();
-			monitor.worked(1);
-
-			updateRepo(tagId);
-			monitor.worked(1);
-
-		} finally {
-			monitor.done();
-		}
-	}
-
-	private void updateRepo(ObjectId tagId) throws TeamException {
-		String refName = Constants.R_TAGS + tag.getTag();
-
-		try {
-			RefUpdate tagRef = repo.updateRef(refName);
-			tagRef.setNewObjectId(tagId);
-
-			tagRef.setForceUpdate(shouldMoveTag);
-			Result updateResult = tagRef.update();
-
-			if (updateResult != Result.NEW && updateResult != Result.FORCED)
-				throw new TeamException(NLS.bind(CoreText.TagOperation_taggingFailure,
-						tag.getTag(), updateResult));
-		} catch (IOException e) {
-			throw new TeamException(NLS.bind(CoreText.TagOperation_taggingFailure,
-					tag.getTag(), e.getMessage()), e);
-		}
-	}
-
-	private ObjectId updateTagObject() throws TeamException {
-		ObjectId startPointRef = tag.getObjectId();
-
-		try {
-			ObjectId tagId;
-			repo.open(startPointRef);
-			ObjectInserter inserter = repo.newObjectInserter();
-			try {
-				tagId = inserter.insert(tag);
-				inserter.flush();
-			} finally {
-				inserter.release();
-			}
-			return tagId;
-		} catch (IOException e) {
-			throw new TeamException(NLS.bind(CoreText.TagOperation_objectIdNotFound,
-					tag.getTag(), e.getMessage()), e);
-		}
-	}
-
-
-	public ISchedulingRule getSchedulingRule() {
-		return null;
-	}
-
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/UntrackOperation.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/op/UntrackOperation.java
deleted file mode 100644
index 507e136..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/op/UntrackOperation.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2007, Robin Rosenberg <robin.rosenberg@dewire.com>
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * Copyright (C) 2008, Google Inc.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.op;
-
-import java.io.IOException;
-import java.util.Collection;
-import java.util.IdentityHashMap;
-import java.util.Map;
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.jobs.ISchedulingRule;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.CoreText;
-import org.eclipse.egit.core.internal.job.RuleUtil;
-import org.eclipse.egit.core.project.GitProjectData;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.jgit.dircache.DirCacheEditor;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.osgi.util.NLS;
-
-/**
- * Remove one or more existing files/folders from the Git repository.
- * <p>
- * Accepts a collection of resources (files and/or directories) which should be
- * removed from the their corresponding Git repositories. Resources in the
- * collection can be associated with multiple repositories. The operation will
- * automatically remove each resource from the correct Git repository.
- * </p>
- * <p>
- * Resources are only scheduled for removal in the index-
- * </p>
- */
-public class UntrackOperation implements IEGitOperation {
-	private final Collection<? extends IResource> rsrcList;
-
-	private final IdentityHashMap<Repository, DirCacheEditor> edits;
-
-	private final IdentityHashMap<RepositoryMapping, Object> mappings;
-
-	/**
-	 * Create a new operation to stop tracking existing files/folders.
-	 *
-	 * @param rsrcs
-	 *            collection of {@link IResource}s which should be removed from
-	 *            the relevant Git repositories.
-	 */
-	public UntrackOperation(final Collection<? extends IResource> rsrcs) {
-		rsrcList = rsrcs;
-		edits = new IdentityHashMap<Repository, DirCacheEditor>();
-		mappings = new IdentityHashMap<RepositoryMapping, Object>();
-	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.egit.core.op.IEGitOperation#execute(org.eclipse.core.runtime.IProgressMonitor)
-	 */
-	public void execute(IProgressMonitor m) throws CoreException {
-		IProgressMonitor monitor;
-		if (m == null)
-			monitor = new NullProgressMonitor();
-		else
-			monitor = m;
-
-		edits.clear();
-		mappings.clear();
-
-		monitor.beginTask(CoreText.UntrackOperation_adding, rsrcList.size() * 200);
-		try {
-			for (IResource obj : rsrcList) {
-				remove(obj);
-				monitor.worked(200);
-			}
-
-			for (Map.Entry<Repository, DirCacheEditor> e : edits.entrySet()) {
-				final Repository db = e.getKey();
-				final DirCacheEditor editor = e.getValue();
-				monitor.setTaskName(NLS.bind(CoreText.UntrackOperation_writingIndex, db.getDirectory()));
-				editor.commit();
-			}
-		} catch (RuntimeException e) {
-			throw new CoreException(Activator.error(CoreText.UntrackOperation_failed, e));
-		} catch (IOException e) {
-			throw new CoreException(Activator.error(CoreText.UntrackOperation_failed, e));
-		} finally {
-			for (final RepositoryMapping rm : mappings.keySet())
-				rm.fireRepositoryChanged();
-			for (DirCacheEditor editor:edits.values())
-				if (editor.getDirCache() != null)
-					editor.getDirCache().unlock();
-			edits.clear();
-			mappings.clear();
-			monitor.done();
-		}
-	}
-
-	/* (non-Javadoc)
-	 * @see org.eclipse.egit.core.op.IEGitOperation#getSchedulingRule()
-	 */
-	public ISchedulingRule getSchedulingRule() {
-		return RuleUtil.getRuleForRepositories(rsrcList.toArray(new IResource[rsrcList.size()]));
-	}
-
-	private void remove(final IResource path) throws CoreException {
-		final IProject proj = path.getProject();
-		final GitProjectData pd = GitProjectData.get(proj);
-		if (pd == null)
-			return;
-		final RepositoryMapping rm = pd.getRepositoryMapping(path);
-		if (rm == null)
-			return;
-		final Repository db = rm.getRepository();
-
-		DirCacheEditor e = edits.get(db);
-		if (e == null) {
-			try {
-				e = db.lockDirCache().editor();
-			} catch (IOException err) {
-				throw new CoreException(Activator.error(CoreText.UntrackOperation_failed, err));
-			}
-			edits.put(db, e);
-			mappings.put(rm, rm);
-		}
-
-		if (path instanceof IContainer)
-			e.add(new DirCacheEditor.DeleteTree(rm.getRepoRelativePath(path)));
-		else
-			e.add(new DirCacheEditor.DeletePath(rm.getRepoRelativePath(path)));
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/project/GitProjectData.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/project/GitProjectData.java
deleted file mode 100644
index 633180b..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/project/GitProjectData.java
+++ /dev/null
@@ -1,551 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * Copyright (C) 2008, Google Inc.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.project;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IResourceChangeEvent;
-import org.eclipse.core.resources.IResourceChangeListener;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.QualifiedName;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.core.runtime.preferences.DefaultScope;
-import org.eclipse.core.runtime.preferences.IEclipsePreferences;
-import org.eclipse.core.runtime.preferences.InstanceScope;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.CoreText;
-import org.eclipse.egit.core.GitCorePreferences;
-import org.eclipse.egit.core.GitProvider;
-import org.eclipse.egit.core.JobFamilies;
-import org.eclipse.egit.core.internal.trace.GitTraceLocation;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.internal.storage.file.WindowCache;
-import org.eclipse.jgit.storage.file.WindowCacheConfig;
-import org.eclipse.jgit.util.FileUtils;
-import org.eclipse.osgi.util.NLS;
-import org.eclipse.team.core.RepositoryProvider;
-
-/**
- * This class keeps information about how a project is mapped to
- * a Git repository.
- */
-public class GitProjectData {
-
-	private static final Map<IProject, GitProjectData> projectDataCache = new HashMap<IProject, GitProjectData>();
-
-	private static Set<RepositoryChangeListener> repositoryChangeListeners = new HashSet<RepositoryChangeListener>();
-
-	@SuppressWarnings("synthetic-access")
-	private static final IResourceChangeListener rcl = new RCL();
-
-	private static class RCL implements IResourceChangeListener {
-		@SuppressWarnings("synthetic-access")
-		public void resourceChanged(final IResourceChangeEvent event) {
-			switch (event.getType()) {
-			case IResourceChangeEvent.PRE_CLOSE:
-				uncache((IProject) event.getResource());
-				break;
-			case IResourceChangeEvent.PRE_DELETE:
-				try {
-					delete((IProject) event.getResource());
-				} catch (IOException e) {
-					Activator.logError(e.getMessage(), e);
-				}
-				break;
-			default:
-				break;
-			}
-		}
-	}
-
-	private static QualifiedName MAPPING_KEY = new QualifiedName(
-			GitProjectData.class.getName(), "RepositoryMapping");  //$NON-NLS-1$
-
-	/**
-	 * Start listening for resource changes.
-	 *
-	 * @param includeChange true to listen to content changes
-	 */
-	public static void attachToWorkspace(final boolean includeChange) {
-		trace("attachToWorkspace - addResourceChangeListener");  //$NON-NLS-1$
-		ResourcesPlugin.getWorkspace().addResourceChangeListener(
-				rcl,
-				(includeChange ? IResourceChangeEvent.POST_CHANGE : 0)
-						| IResourceChangeEvent.PRE_CLOSE
-						| IResourceChangeEvent.PRE_DELETE);
-	}
-
-	/**
-	 * Stop listening to resource changes
-	 */
-	public static void detachFromWorkspace() {
-		trace("detachFromWorkspace - removeResourceChangeListener"); //$NON-NLS-1$
-		ResourcesPlugin.getWorkspace().removeResourceChangeListener(rcl);
-	}
-
-	/**
-	 * Register a new listener for repository modification events.
-	 * <p>
-	 * This is a no-op if <code>objectThatCares</code> has already been
-	 * registered.
-	 * </p>
-	 *
-	 * @param objectThatCares
-	 *            the new listener to register. Must not be null.
-	 */
-	public static synchronized void addRepositoryChangeListener(
-			final RepositoryChangeListener objectThatCares) {
-		if (objectThatCares == null)
-			throw new NullPointerException();
-		repositoryChangeListeners.add(objectThatCares);
-	}
-
-	/**
-	 * Remove a registered {@link RepositoryChangeListener}
-	 *
-	 * @param objectThatCares
-	 *            The listener to remove
-	 */
-	public static synchronized void removeRepositoryChangeListener(
-			final RepositoryChangeListener objectThatCares) {
-		repositoryChangeListeners.remove(objectThatCares);
-	}
-
-	/**
-	 * Notify registered {@link RepositoryChangeListener}s of a change.
-	 *
-	 * @param which
-	 *            the repository which has had changes occur within it.
-	 */
-	static void fireRepositoryChanged(final RepositoryMapping which) {
-		Job job = new Job(CoreText.GitProjectData_repositoryChangedJobName) {
-
-			@Override
-			protected IStatus run(IProgressMonitor monitor) {
-				RepositoryChangeListener[] listeners = getRepositoryChangeListeners();
-				monitor.beginTask(
-						CoreText.GitProjectData_repositoryChangedTaskName,
-						listeners.length);
-
-				for (RepositoryChangeListener listener : listeners) {
-					listener.repositoryChanged(which);
-					monitor.worked(1);
-				}
-
-				monitor.done();
-
-				return Status.OK_STATUS;
-			}
-
-			@Override
-			public boolean belongsTo(Object family) {
-				if (JobFamilies.REPOSITORY_CHANGED.equals(family))
-					return true;
-
-				return super.belongsTo(family);
-			}
-		};
-
-		job.schedule();
-	}
-
-	/**
-	 * Get a copy of the current set of repository change listeners
-	 * <p>
-	 * The array has no references, so is safe for iteration and modification
-	 *
-	 * @return a copy of the current repository change listeners
-	 */
-	private static synchronized RepositoryChangeListener[] getRepositoryChangeListeners() {
-		return repositoryChangeListeners
-				.toArray(new RepositoryChangeListener[repositoryChangeListeners
-						.size()]);
-	}
-
-	/**
-	 * @param p
-	 * @return {@link GitProjectData} for the specified project
-	 */
-	public synchronized static GitProjectData get(final IProject p) {
-		try {
-			GitProjectData d = lookup(p);
-			if (d == null
-					&& RepositoryProvider.getProvider(p) instanceof GitProvider) {
-				d = new GitProjectData(p).load();
-				cache(p, d);
-			}
-			return d;
-		} catch (IOException err) {
-			Activator.logError(CoreText.GitProjectData_missing, err);
-			return null;
-		}
-	}
-
-	/**
-	 * Drop the Eclipse project from our association of projects/repositories
-	 *
-	 * @param p
-	 *            Eclipse project
-	 * @throws IOException
-	 *             if deletion of property files failed
-	 */
-	public static void delete(final IProject p) throws IOException {
-		trace("delete(" + p.getName() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
-		GitProjectData d = lookup(p);
-		if (d == null)
-			deletePropertyFiles(p);
-		else
-			d.deletePropertyFilesAndUncache();
-	}
-
-	/**
-	 * Add the Eclipse project to our association of projects/repositories
-	 *
-	 * @param p
-	 *            Eclipse project
-	 * @param d
-	 *            {@link GitProjectData} associated with this project
-	 */
-	public static void add(final IProject p, final GitProjectData d) {
-		trace("add(" + p.getName() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
-
-		cache(p, d);
-	}
-
-	static void trace(final String m) {
-		// TODO is this the right location?
-		if (GitTraceLocation.CORE.isActive())
-			GitTraceLocation.getTrace().trace(
-					GitTraceLocation.CORE.getLocation(),
-					"(GitProjectData) " + m); //$NON-NLS-1$
-	}
-
-	private synchronized static void cache(final IProject p,
-			final GitProjectData d) {
-		projectDataCache.put(p, d);
-	}
-
-	private synchronized static void uncache(final IProject p) {
-		if (projectDataCache.remove(p) != null) {
-			trace("uncacheDataFor(" //$NON-NLS-1$
-				+ p.getName() + ")"); //$NON-NLS-1$
-		}
-	}
-
-	private synchronized static GitProjectData lookup(final IProject p) {
-		return projectDataCache.get(p);
-	}
-
-	/**
-	 * Update the settings for the global window cache of the workspace.
-	 */
-	public static void reconfigureWindowCache() {
-		final WindowCacheConfig c = new WindowCacheConfig();
-		IEclipsePreferences d = DefaultScope.INSTANCE.getNode(Activator.getPluginId());
-		IEclipsePreferences p = InstanceScope.INSTANCE.getNode(Activator.getPluginId());
-		c.setPackedGitLimit(p.getInt(GitCorePreferences.core_packedGitLimit, d.getInt(GitCorePreferences.core_packedGitLimit, 0)));
-		c.setPackedGitWindowSize(p.getInt(GitCorePreferences.core_packedGitWindowSize, d.getInt(GitCorePreferences.core_packedGitWindowSize, 0)));
-		c.setPackedGitMMAP(p.getBoolean(GitCorePreferences.core_packedGitMMAP, d.getBoolean(GitCorePreferences.core_packedGitMMAP, false)));
-		c.setDeltaBaseCacheLimit(p.getInt(GitCorePreferences.core_deltaBaseCacheLimit, d.getInt(GitCorePreferences.core_deltaBaseCacheLimit, 0)));
-		c.setStreamFileThreshold(p.getInt(GitCorePreferences.core_streamFileThreshold, d.getInt(GitCorePreferences.core_streamFileThreshold, 0)));
-		WindowCache.reconfigure(c);
-	}
-
-	private final IProject project;
-
-	private final Collection<RepositoryMapping> mappings = new ArrayList<RepositoryMapping>();
-
-	private final Set<IResource> protectedResources = new HashSet<IResource>();
-
-	/**
-	 * Construct a {@link GitProjectData} for the mapping
-	 * of a project.
-	 *
-	 * @param p Eclipse project
-	 */
-	public GitProjectData(final IProject p) {
-		project = p;
-	}
-
-	/**
-	 * @return the Eclipse project mapped through this resource.
-	 */
-	public IProject getProject() {
-		return project;
-	}
-
-	/**
-	 * Set repository mappings
-	 *
-	 * @param newMappings
-	 */
-	public void setRepositoryMappings(final Collection<RepositoryMapping> newMappings) {
-		mappings.clear();
-		mappings.addAll(newMappings);
-		remapAll();
-	}
-
-	/**
-	 * Hide our private parts from the navigators other browsers.
-	 *
-	 * @throws CoreException
-	 */
-	public void markTeamPrivateResources() throws CoreException {
-		for (final Object rmObj : mappings) {
-			final RepositoryMapping rm = (RepositoryMapping)rmObj;
-			final IContainer c = rm.getContainer();
-			if (c == null)
-				continue; // Not fully mapped yet?
-
-			final IResource dotGit = c.findMember(Constants.DOT_GIT);
-			if (dotGit != null) {
-				try {
-					final Repository r = rm.getRepository();
-					final File dotGitDir = dotGit.getLocation().toFile()
-							.getCanonicalFile();
-					if (dotGitDir.equals(r.getDirectory())) {
-						trace("teamPrivate " + dotGit);  //$NON-NLS-1$
-						dotGit.setTeamPrivateMember(true);
-					}
-				} catch (IOException err) {
-					throw new CoreException(Activator.error(CoreText.Error_CanonicalFile, err));
-				}
-			}
-		}
-	}
-
-	/**
-	 * @param f
-	 * @return true if a resource is protected in this repository
-	 */
-	public boolean isProtected(final IResource f) {
-		return protectedResources.contains(f);
-	}
-
-	/**
-	 * @param resource any workbench resource contained within this project.
-	 * @return the mapping for the specified project
-	 */
-	public RepositoryMapping getRepositoryMapping(IResource resource) {
-		IResource r = resource;
-		try {
-			for (; r != null; r = r.getParent()) {
-				final RepositoryMapping m;
-
-				if (!r.isAccessible())
-					continue;
-				m = (RepositoryMapping) r.getSessionProperty(MAPPING_KEY);
-				if (m != null)
-					return m;
-			}
-		} catch (CoreException err) {
-			Activator.logError(
-					CoreText.GitProjectData_failedFindingRepoMapping, err);
-		}
-		return null;
-	}
-
-	private void deletePropertyFilesAndUncache() throws IOException {
-		deletePropertyFiles(getProject());
-		uncache(getProject());
-	}
-
-	private static void deletePropertyFiles(IProject project) throws IOException {
-		final File dir = propertyFile(project).getParentFile();
-		FileUtils.delete(dir, FileUtils.RECURSIVE);
-		trace("deleteDataFor(" //$NON-NLS-1$
-				+ project.getName() + ")"); //$NON-NLS-1$
-	}
-
-	/**
-	 * Store information about the repository connection in the workspace
-	 *
-	 * @throws CoreException
-	 */
-	public void store() throws CoreException {
-		final File dat = propertyFile();
-		final File tmp;
-		boolean ok = false;
-
-		try {
-			trace("save " + dat);  //$NON-NLS-1$
-			tmp = File.createTempFile(
-					"gpd_",  //$NON-NLS-1$
-					".prop",   //$NON-NLS-1$
-					dat.getParentFile());
-			final FileOutputStream o = new FileOutputStream(tmp);
-			try {
-				final Properties p = new Properties();
-				for (final RepositoryMapping repoMapping : mappings) {
-					repoMapping.store(p);
-				}
-				p.store(o, "GitProjectData");  //$NON-NLS-1$
-				ok = true;
-			} finally {
-				o.close();
-				if (!ok && tmp.exists()) {
-					FileUtils.delete(tmp);
-				}
-			}
-			if (dat.exists())
-				FileUtils.delete(dat);
-			if (!tmp.renameTo(dat)) {
-				if (tmp.exists())
-					FileUtils.delete(tmp);
-				throw new CoreException(
-						Activator.error(NLS.bind(
-								CoreText.GitProjectData_saveFailed, dat), null));
-			}
-		} catch (IOException ioe) {
-			throw new CoreException(Activator.error(
-					NLS.bind(CoreText.GitProjectData_saveFailed, dat), ioe));
-		}
-	}
-
-	private File propertyFile() {
-		return propertyFile(getProject());
-	}
-
-	private static File propertyFile(IProject project) {
-		return new File(project.getWorkingLocation(Activator.getPluginId())
-				.toFile(), "GitProjectData.properties"); //$NON-NLS-1$
-	}
-
-	private GitProjectData load() throws IOException {
-		final File dat = propertyFile();
-		trace("load " + dat);  //$NON-NLS-1$
-
-		final FileInputStream o = new FileInputStream(dat);
-		try {
-			final Properties p = new Properties();
-			p.load(o);
-
-			mappings.clear();
-			for (final Object keyObj : p.keySet()) {
-				final String key = keyObj.toString();
-				if (RepositoryMapping.isInitialKey(key)) {
-					mappings.add(new RepositoryMapping(p, key));
-				}
-			}
-		} finally {
-			o.close();
-		}
-
-		remapAll();
-		return this;
-	}
-
-	private void remapAll() {
-		protectedResources.clear();
-		for (final RepositoryMapping repoMapping : mappings) {
-			map(repoMapping);
-		}
-	}
-
-	private void map(final RepositoryMapping m) {
-		final IResource r;
-		final File git;
-		final IResource dotGit;
-		IContainer c = null;
-
-		m.clear();
-		r = getProject().findMember(m.getContainerPath());
-		if (r instanceof IContainer) {
-			c = (IContainer) r;
-		} else if (r != null) {
-			c = (IContainer) r.getAdapter(IContainer.class);
-		}
-
-		if (c == null) {
-			logGoneMappedResource(m);
-			m.clear();
-			return;
-		}
-		m.setContainer(c);
-
-		git = c.getLocation().append(m.getGitDirPath()).toFile();
-		if (!git.isDirectory() || !new File(git, "config").isFile()) { //$NON-NLS-1$
-			logGoneMappedResource(m);
-			m.clear();
-			return;
-		}
-
-		try {
-			m.setRepository(Activator.getDefault().getRepositoryCache()
-					.lookupRepository(git));
-		} catch (IOException ioe) {
-			logGoneMappedResource(m);
-			m.clear();
-			return;
-		}
-
-		m.fireRepositoryChanged();
-
-		trace("map "  //$NON-NLS-1$
-				+ c
-				+ " -> "  //$NON-NLS-1$
-				+ m.getRepository());
-		try {
-			c.setSessionProperty(MAPPING_KEY, m);
-		} catch (CoreException err) {
-			Activator.logError(
-					CoreText.GitProjectData_failedToCacheRepoMapping, err);
-		}
-
-		dotGit = c.findMember(Constants.DOT_GIT);
-		if (dotGit != null && dotGit.getLocation().toFile().equals(git)) {
-			protect(dotGit);
-		}
-	}
-
-	private void logGoneMappedResource(final RepositoryMapping m) {
-		Activator.logError(MessageFormat.format(
-				CoreText.GitProjectData_mappedResourceGone, m.toString()),
-				new FileNotFoundException(m.getContainerPath().toString()));
-	}
-
-	private void protect(IResource resource) {
-		IResource c = resource;
-		while (c != null && !c.equals(getProject())) {
-			trace("protect " + c);  //$NON-NLS-1$
-			protectedResources.add(c);
-			try {
-				c.setTeamPrivateMember(true);
-			} catch (CoreException e) {
-				Activator.logError(MessageFormat.format(
-						CoreText.GitProjectData_FailedToMarkTeamPrivate,
-						c.getFullPath()),
-						e);
-			}
-			c = c.getParent();
-		}
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/project/RepositoryChangeListener.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/project/RepositoryChangeListener.java
deleted file mode 100644
index d07fb8e..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/project/RepositoryChangeListener.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2007, Shawn O. Pearce <spearce@spearce.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.project;
-
-/**
- * Receives notification of a repository change event.
- * <p>
- * A change listener may be called from any thread, especially background job
- * threads, but also from the UI thread. Implementors are encouraged to complete
- * quickly, and make arrange for their tasks to run on the UI event thread if
- * necessary.
- * </p>
- */
-public interface RepositoryChangeListener {
-	/**
-	 * Invoked when a repository has had some or all of its contents change.
-	 *
-	 * @param which
-	 *            the affected repository. Never null.
-	 */
-	public void repositoryChanged(RepositoryMapping which);
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/project/RepositoryFinder.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/project/RepositoryFinder.java
deleted file mode 100644
index cc5cc01..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/project/RepositoryFinder.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2007, Robin Rosenberg <robin.rosenberg@dewire.com>
- * Copyright (C) 2007, Shawn O. Pearce <spearce@spearce.org>
- * Copyright (C) 2008, Google Inc.
- * Copyright (C) 2012, François Rey <eclipse.org_@_francois_._rey_._name>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.project;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.egit.core.CoreText;
-import org.eclipse.egit.core.internal.trace.GitTraceLocation;
-import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.util.SystemReader;
-
-/**
- * Searches for existing Git repositories associated with a project's files.
- * <p>
- * This finder algorithm searches a project's contained files to see if any of
- * them are located within the working directory of an existing Git repository.
- * By default linked resources are ignored and not included in the search.
- * </p>
- * <p>
- * The search algorithm is exhaustive, it will find all matching repositories.
- * For the project itself and possibly for each linked container within the
- * project it scans down the local filesystem trees to locate any Git
- * repositories which may be found there. It also scans up the local filesystem
- * tree to locate any Git repository which may be outside of Eclipse's
- * workspace-view of the world.
- * In short, if there is a Git repository associated, it finds it.
- * </p>
- */
-public class RepositoryFinder {
-	private final IProject proj;
-
-	private final Collection<RepositoryMapping> results = new ArrayList<RepositoryMapping>();
-	private final Set<File> gitdirs = new HashSet<File>();
-
-	private Set<String> ceilingDirectories = new HashSet<String>();
-
-	/**
-	 * Create a new finder to locate Git repositories for a project.
-	 *
-	 * @param p
-	 *            the project this new finder should locate the existing Git
-	 *            repositories of.
-	 */
-	public RepositoryFinder(final IProject p) {
-		proj = p;
-		String ceilingDirectoriesVar = SystemReader.getInstance().getenv(
-				Constants.GIT_CEILING_DIRECTORIES_KEY);
-		if (ceilingDirectoriesVar != null) {
-			ceilingDirectories.addAll(Arrays.asList(ceilingDirectoriesVar
-					.split(File.pathSeparator)));
-		}
-	}
-
-	/**
-	 * Run the search algorithm, ignoring linked resources.
-	 *
-	 * @param m
-	 *            a progress monitor to report feedback to; may be null.
-	 * @return all found {@link RepositoryMapping} instances associated with the
-	 *         project supplied to this instance's constructor.
-	 * @throws CoreException
-	 *             Eclipse was unable to access its workspace, and threw up on
-	 *             us. We're throwing it back at the caller.
-	 */
-	public Collection<RepositoryMapping> find(IProgressMonitor m)
-			throws CoreException {
-		return find(m, false);
-	}
-
-	/**
-	 * Run the search algorithm.
-	 *
-	 * @param m
-	 *            a progress monitor to report feedback to; may be null.
-	 * @param searchLinkedFolders
-	 *            specify if linked folders should be included in the search
-	 * @return all found {@link RepositoryMapping} instances associated with the
-	 *         project supplied to this instance's constructor.
-	 * @throws CoreException
-	 *             Eclipse was unable to access its workspace, and threw up on
-	 *             us. We're throwing it back at the caller.
-	 * @since 2.3
-	 */
-	public Collection<RepositoryMapping> find(IProgressMonitor m, boolean searchLinkedFolders)
-			throws CoreException {
-		IProgressMonitor monitor;
-		if (m == null)
-			monitor = new NullProgressMonitor();
-		else
-			monitor = m;
-		find(monitor, proj, searchLinkedFolders);
-		return results;
-	}
-
-	private void find(final IProgressMonitor m, final IContainer c, boolean searchLinkedFolders)
-				throws CoreException {
-		if (!searchLinkedFolders && c.isLinked())
-			return; // Ignore linked folders
-		final IPath loc = c.getLocation();
-
-		m.beginTask("", 101);  //$NON-NLS-1$
-		m.subTask(CoreText.RepositoryFinder_finding);
-		try {
-			if (loc != null) {
-				final File fsLoc = loc.toFile();
-				assert fsLoc.isAbsolute();
-				final File ownCfg = configFor(fsLoc);
-				final IResource[] children;
-
-				if (ownCfg.isFile()) {
-					register(c, ownCfg.getParentFile());
-				}
-				if (c instanceof IProject) {
-					File p = fsLoc.getParentFile();
-					while (p != null) {
-						// TODO is this the right location?
-						if (GitTraceLocation.CORE.isActive())
-							GitTraceLocation.getTrace().trace(
-									GitTraceLocation.CORE.getLocation(),
-									"Looking at candidate dir: " //$NON-NLS-1$
-											+ p);
-						final File pCfg = configFor(p);
-						if (pCfg.isFile()) {
-							register(c, pCfg.getParentFile());
-						}
-						if (ceilingDirectories.contains(p.getPath()))
-							break;
-						p = p.getParentFile();
-					}
-				}
-				m.worked(1);
-
-				children = c.members();
-				if (children != null && children.length > 0) {
-					final int scale = 100 / children.length;
-					for (int k = 0; k < children.length; k++) {
-						final IResource o = children[k];
-						if (o instanceof IContainer
-								&& !o.getName().equals(Constants.DOT_GIT)) {
-							find(new SubProgressMonitor(m, scale),
-									(IContainer) o, searchLinkedFolders);
-						} else {
-							m.worked(scale);
-						}
-					}
-				}
-			}
-		} finally {
-			m.done();
-		}
-	}
-
-	private File configFor(final File fsLoc) {
-		return new File(new File(fsLoc, Constants.DOT_GIT),
-				"config");  //$NON-NLS-1$
-	}
-
-	private void register(final IContainer c, final File gitdir) {
-		File f = gitdir.getAbsoluteFile();
-		if (gitdirs.contains(f))
-			return;
-		gitdirs.add(f);
-		results.add(new RepositoryMapping(c, f));
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/project/RepositoryMapping.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/project/RepositoryMapping.java
deleted file mode 100644
index baf60f7..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/project/RepositoryMapping.java
+++ /dev/null
@@ -1,338 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2007, Dave Watson <dwatson@mimvista.com>
- * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * Copyright (C) 2008, Shunichi Fuji <palglowr@gmail.com>
- * Copyright (C) 2008, Google Inc.
- * Copyright (C) 2012, 2013 Robin Stocker <robin@nibor.org>
- * Copyright (C) 2013, François Rey <eclipse.org_@_francois_._rey_._name>
- * Copyright (C) 2013, Gunnar Wagenknecht <gunnar@wagenknecht.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.project;
-
-import static org.eclipse.egit.core.internal.util.ResourceUtil.isNonWorkspace;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Properties;
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.core.GitProvider;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.team.core.RepositoryProvider;
-
-/**
- * This class provides means to map resources, projects and repositories
- */
-public class RepositoryMapping {
-	static boolean isInitialKey(final String key) {
-		return key.endsWith(".gitdir");  //$NON-NLS-1$
-	}
-
-	private final String containerPathString;
-
-	private IPath containerPath;
-
-	private final String gitDirPathString;
-
-	private IPath gitDirPath;
-
-	private IPath gitDirAbsolutePath;
-
-	private Repository db;
-
-	private String workdirPrefix;
-
-	private IContainer container;
-
-	/**
-	 * Construct a {@link RepositoryMapping} for a previously connected project.
-	 *
-	 * @param p TODO
-	 * @param initialKey TODO
-	 */
-	public RepositoryMapping(final Properties p, final String initialKey) {
-		final int dot = initialKey.lastIndexOf('.');
-
-		containerPathString = initialKey.substring(0, dot);
-		gitDirPathString = p.getProperty(initialKey);
-	}
-
-	/**
-	 * Construct a {@link RepositoryMapping} for previously
-	 * unknown project.
-	 *
-	 * @param mappedContainer
-	 * @param gitDir
-	 */
-	public RepositoryMapping(final IContainer mappedContainer, final File gitDir) {
-		final IPath cLoc = mappedContainer.getLocation()
-				.removeTrailingSeparator();
-		final IPath gLoc = Path.fromOSString(gitDir.getAbsolutePath())
-				.removeTrailingSeparator();
-		final IPath gLocParent = gLoc.removeLastSegments(1);
-
-		container = mappedContainer;
-		containerPathString = container.getProjectRelativePath()
-				.toPortableString();
-
-		if (cLoc.isPrefixOf(gLoc)) {
-			int matchingSegments = gLoc.matchingFirstSegments(cLoc);
-			IPath remainder = gLoc.removeFirstSegments(matchingSegments);
-			String device = remainder.getDevice();
-			if (device == null)
-				gitDirPathString = remainder.toPortableString();
-			else
-				gitDirPathString = remainder.toPortableString().substring(
-						device.length());
-		} else if (gLocParent.isPrefixOf(cLoc)) {
-			int cnt = cLoc.segmentCount() - cLoc.matchingFirstSegments(gLocParent);
-			StringBuilder p = new StringBuilder("");  //$NON-NLS-1$
-			while (cnt-- > 0) {
-				p.append("../");  //$NON-NLS-1$
-			}
-			p.append(gLoc.segment(gLoc.segmentCount() - 1));
-			gitDirPathString = p.toString();
-		} else {
-			gitDirPathString = gLoc.toPortableString();
-		}
-	}
-
-	/**
-	 * @return the container path corresponding to git repository
-	 */
-	public IPath getContainerPath() {
-		if (containerPath == null)
-			containerPath = Path.fromPortableString(containerPathString);
-		return containerPath;
-	}
-
-	IPath getGitDirPath() {
-		if (gitDirPath == null)
-			gitDirPath = Path.fromPortableString(gitDirPathString);
-		return gitDirPath;
-	}
-
-	/**
-	 * @return the workdir file, i.e. where the files are checked out
-	 */
-	public File getWorkTree() {
-		return getRepository().getWorkTree();
-	}
-
-	synchronized void clear() {
-		db = null;
-		workdirPrefix = null;
-		container = null;
-	}
-
-	/**
-	 * @return a reference to the repository object handled by this mapping
-	 */
-	public synchronized Repository getRepository() {
-		return db;
-	}
-
-	synchronized void setRepository(final Repository r) {
-		db = r;
-
-		try {
-			workdirPrefix = getWorkTree().getCanonicalPath();
-		} catch (IOException err) {
-			workdirPrefix = getWorkTree().getAbsolutePath();
-		}
-		workdirPrefix = workdirPrefix.replace('\\', '/');
-		if (!workdirPrefix.endsWith("/"))  //$NON-NLS-1$
-			workdirPrefix += "/";  //$NON-NLS-1$
-	}
-
-	/**
-	 * @return the mapped container (currently project)
-	 */
-	public synchronized IContainer getContainer() {
-		return container;
-	}
-
-	synchronized void setContainer(final IContainer c) {
-		container = c;
-	}
-
-	/**
-	 * Notify registered {@link RepositoryChangeListener}s of a change.
-	 *
-	 * @see GitProjectData#addRepositoryChangeListener(RepositoryChangeListener)
-	 */
-	public void fireRepositoryChanged() {
-		GitProjectData.fireRepositoryChanged(this);
-	}
-
-	synchronized void store(final Properties p) {
-		p.setProperty(containerPathString + ".gitdir", gitDirPathString); //$NON-NLS-1$
-	}
-
-	public String toString() {
-		IPath absolutePath = getGitDirAbsolutePath();
-		return "RepositoryMapping[" //$NON-NLS-1$
-				+ format(containerPathString)
-				+ " -> '" //$NON-NLS-1$
-				+ format(gitDirPathString)
-				+ "', absolute path: '"  //$NON-NLS-1$
-				+ format(absolutePath) + "' ]"; //$NON-NLS-1$
-	}
-
-	private String format(Object o) {
-		if (o == null)
-			return "<null>"; //$NON-NLS-1$
-		else if (o.toString().length() == 0)
-			return "<empty>"; //$NON-NLS-1$
-		else
-			return o.toString();
-	}
-
-	/**
-	 * This method should only be called for resources that are actually in this
-	 * repository, so we can safely assume that their path prefix matches
-	 * {@link #getWorkTree()}. Testing that here is rather expensive so we don't
-	 * bother.
-	 *
-	 * @param rsrc
-	 * @return the path relative to the Git repository, including base name. An
-	 *         empty string (<code>""</code>) if passed resource corresponds to
-	 *         working directory (root). <code>null</code> if the path cannot be
-	 *         determined.
-	 */
-	public String getRepoRelativePath(final IResource rsrc) {
-		IPath location = rsrc.getLocation();
-		if (location == null)
-			return null;
-		return getRepoRelativePath(location);
-	}
-
-	/**
-	 * This method should only be called for resources that are actually in this
-	 * repository, so we can safely assume that their path prefix matches
-	 * {@link #getWorkTree()}. Testing that here is rather expensive so we don't
-	 * bother.
-	 *
-	 * @param location
-	 * @return the path relative to the Git repository, including base name. An
-	 *         empty string (<code>""</code>) if passed location corresponds to
-	 *         working directory (root). <code>null</code> if the path cannot be
-	 *         determined.
-	 */
-	public String getRepoRelativePath(IPath location) {
-		final int pfxLen = workdirPrefix.length();
-		final String p = location.toString();
-		final int pLen = p.length();
-		if (pLen > pfxLen)
-			return p.substring(pfxLen);
-		if (pLen == pfxLen - 1)
-			return ""; //$NON-NLS-1$
-		return null;
-	}
-
-	/**
-	 * Get the repository mapping for a resource. If the given resource is a
-	 * linked resource, the raw location of the resource will be used to
-	 * determine a repository mapping.
-	 *
-	 * @param resource
-	 * @return the RepositoryMapping for this resource, or null for non
-	 *         GitProvider.
-	 */
-	public static RepositoryMapping getMapping(final IResource resource) {
-		if (isNonWorkspace(resource))
-			return null;
-
-		if (resource.isLinked(IResource.CHECK_ANCESTORS))
-			return getMapping(resource.getLocation());
-
-		IProject project = resource.getProject();
-		if (project == null)
-			return null;
-
-		final RepositoryProvider rp = RepositoryProvider.getProvider(project);
-		if (!(rp instanceof GitProvider))
-			return null;
-
-		if (((GitProvider)rp).getData() == null)
-			return null;
-
-		return ((GitProvider)rp).getData().getRepositoryMapping(resource);
-	}
-
-	/**
-	 * Get the repository mapping for a path if it exists.
-	 *
-	 * @param path
-	 * @return the RepositoryMapping for this path,
-	 *         or null for non GitProvider.
-	 */
-	public static RepositoryMapping getMapping(IPath path) {
-		IProject[] projects = ResourcesPlugin.getWorkspace().getRoot()
-				.getProjects();
-
-		for (IProject project : projects) {
-			if (isNonWorkspace(project))
-				continue;
-			RepositoryMapping mapping = getMapping(project);
-			if (mapping == null)
-				continue;
-
-			IPath workingTree = new Path(mapping.getWorkTree().toString());
-			if (workingTree.isPrefixOf(path))
-				return mapping;
-		}
-
-		return null;
-	}
-
-	/**
-	 * Finds a RepositoryMapping related to a given repository
-	 *
-	 * @param repository
-	 * @return a RepositoryMapping related to repository. Null if no
-	 *         RepositoryMapping exists.
-	 */
-	public static RepositoryMapping findRepositoryMapping(Repository repository) {
-		final IProject[] projects = ResourcesPlugin.getWorkspace().getRoot()
-				.getProjects();
-		for (IProject project : projects) {
-			RepositoryMapping mapping = RepositoryMapping.getMapping(project);
-			if (mapping != null && mapping.getRepository() == repository)
-				return mapping;
-		}
-		return null;
-	}
-
-	/**
-	 * @return the name of the .git directory
-	 */
-	public String getGitDir() {
-		return gitDirPathString;
-	}
-
-	/**
-	 * @return The GIT DIR absolute path
-	 */
-	public synchronized IPath getGitDirAbsolutePath() {
-		if (gitDirAbsolutePath == null) {
-			if (container != null) {
-				IPath cloc = container.getLocation();
-				if (cloc != null)
-					gitDirAbsolutePath = cloc.append(getGitDirPath());
-			}
-		}
-		return gitDirAbsolutePath;
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/securestorage/EGitSecureStore.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/securestorage/EGitSecureStore.java
deleted file mode 100644
index 3c71cc8..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/securestorage/EGitSecureStore.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2010, Jens Baumgart <jens.baumgart@sap.com>
- * Copyright (C) 2010, Edwin Kempin <edwin.kempin@sap.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.securestorage;
-
-import java.io.IOException;
-
-import org.eclipse.equinox.security.storage.EncodingUtils;
-import org.eclipse.equinox.security.storage.ISecurePreferences;
-import org.eclipse.equinox.security.storage.StorageException;
-import org.eclipse.jgit.transport.URIish;
-
-/**
- * This class wraps the Eclipse secure store. It provides methods to put
- * credentials for a given URI to the secure store and to retrieve credentials
- * for a given URI.
- */
-public class EGitSecureStore {
-
-	private static final String USER = "user"; //$NON-NLS-1$
-
-	private static final String PASSWORD = "password"; //$NON-NLS-1$
-
-	private static final String GIT_PATH_PREFIX = "/GIT/"; //$NON-NLS-1$
-
-	private final ISecurePreferences preferences;
-
-	/**
-	 * Constructor
-	 *
-	 * @param preferences
-	 *            the Eclipse secure store should be passed here if not in test
-	 *            mode
-	 */
-	public EGitSecureStore(ISecurePreferences preferences) {
-		this.preferences = preferences;
-	}
-
-	/**
-	 * Puts credentials for the given URI into the secure store
-	 *
-	 * @param uri
-	 * @param credentials
-	 * @throws StorageException
-	 * @throws IOException
-	 */
-	public void putCredentials(URIish uri, UserPasswordCredentials credentials)
-			throws StorageException, IOException {
-		String pathName = calcNodePath(uri);
-		ISecurePreferences node = preferences.node(pathName);
-		node.put(USER, credentials.getUser(), false);
-		node.put(PASSWORD, credentials.getPassword(), true);
-		node.flush();
-	}
-
-	/**
-	 * Retrieves credentials stored for the given URI from the secure store
-	 *
-	 * @param uri
-	 * @return credentials
-	 * @throws StorageException
-	 */
-	public UserPasswordCredentials getCredentials(URIish uri)
-			throws StorageException {
-		String pathName = calcNodePath(uri);
-		if (!preferences.nodeExists(pathName))
-			return null;
-		ISecurePreferences node = preferences.node(pathName);
-		String user = node.get(USER, ""); //$NON-NLS-1$
-		String password = node.get(PASSWORD, ""); //$NON-NLS-1$
-		if (uri.getUser() != null && !user.equals(uri.getUser()))
-			return null;
-		return new UserPasswordCredentials(user, password);
-	}
-
-	static String calcNodePath(URIish uri) {
-		URIish storedURI = uri.setUser(null).setPass(null).setPath(null);
-		if (uri.getPort() == -1) {
-			String s = uri.getScheme();
-			if ("http".equals(s)) //$NON-NLS-1$
-				storedURI = storedURI.setPort(80);
-			else if ("https".equals(s)) //$NON-NLS-1$
-				storedURI = storedURI.setPort(443);
-			else if ("ssh".equals(s) || "sftp".equals(s)) //$NON-NLS-1$ //$NON-NLS-2$
-				storedURI = storedURI.setPort(22);
-			else if ("ftp".equals(s)) //$NON-NLS-1$
-				storedURI = storedURI.setPort(21);
-		}
-		String pathName = GIT_PATH_PREFIX
-				+ EncodingUtils.encodeSlashes(storedURI.toString());
-		return pathName;
-	}
-
-	/**
-	 * Clear credentials for the given uri.
-	 *
-	 * @param uri
-	 * @throws IOException
-	 */
-	public void clearCredentials(URIish uri) throws IOException {
-		String pathName = calcNodePath(uri);
-		if (!preferences.nodeExists(pathName))
-			return;
-		ISecurePreferences node = preferences.node(pathName);
-		node.removeNode();
-		node.flush();
-	}
-
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/securestorage/UserPasswordCredentials.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/securestorage/UserPasswordCredentials.java
deleted file mode 100644
index b84ab5d..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/securestorage/UserPasswordCredentials.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2010, Jens Baumgart <jens.baumgart@sap.com>
- * Copyright (C) 2010, Edwin Kempin <edwin.kempin@sap.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.securestorage;
-
-/**
- * Implements a credentials object containing user and password.
- */
-public class UserPasswordCredentials {
-
-	private final String user;
-	private final String password;
-
-	/**
-	 * @param user
-	 * @param password
-	 */
-	public UserPasswordCredentials(String user, String password) {
-		this.user = user;
-		this.password = password;
-	}
-
-	/**
-	 * @return user
-	 */
-	public String getUser() {
-		return user;
-	}
-
-	/**
-	 * @return password
-	 */
-	public String getPassword() {
-		return password;
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitBaseResourceVariantTree.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitBaseResourceVariantTree.java
deleted file mode 100644
index 0483cc3..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitBaseResourceVariantTree.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     IBM Corporation - initial API and implementation
- *     Dariusz Luksza <dariusz@luksza.org>
- *******************************************************************************/
-package org.eclipse.egit.core.synchronize;
-
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.team.core.variants.SessionResourceVariantByteStore;
-
-class GitBaseResourceVariantTree extends GitResourceVariantTree {
-
-	public GitBaseResourceVariantTree(GitSyncCache cache, GitSynchronizeDataSet gsds) {
-		super(new SessionResourceVariantByteStore(), cache, gsds);
-	}
-
-	@Override
-	protected ObjectId getObjectId(ThreeWayDiffEntry diffEntry) {
-		return diffEntry.getBaseId().toObjectId();
-	}
-
-	@Override
-	protected RevCommit getCommitId(GitSynchronizeData gsd) {
-		return gsd.getDstRevCommit();
-	}
-
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitCommitsModelCache.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitCommitsModelCache.java
deleted file mode 100644
index f90a9e2..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitCommitsModelCache.java
+++ /dev/null
@@ -1,456 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2011, 2012 Dariusz Luksza <dariusz@luksza.org> and others.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.synchronize;
-
-import static org.eclipse.jgit.lib.ObjectId.zeroId;
-import static org.eclipse.jgit.treewalk.filter.TreeFilter.ANY_DIFF;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.eclipse.jgit.lib.AbbreviatedObjectId;
-import org.eclipse.jgit.lib.MutableObjectId;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.jgit.revwalk.RevFlag;
-import org.eclipse.jgit.revwalk.RevFlagSet;
-import org.eclipse.jgit.revwalk.RevWalk;
-import org.eclipse.jgit.treewalk.EmptyTreeIterator;
-import org.eclipse.jgit.treewalk.TreeWalk;
-import org.eclipse.jgit.treewalk.filter.AndTreeFilter;
-import org.eclipse.jgit.treewalk.filter.TreeFilter;
-
-/**
- * Retrieves list of commits and the changes associated with each commit
- */
-public class GitCommitsModelCache {
-
-	/**
-	 * Constant copied from org.eclipse.compare.structuremergeviewer.Differencer.ADDITION
-	 * in order to avoid UI dependencies introduced by the org.eclipse.compare bundle
-	 */
-	public static final int ADDITION = 1;
-
-	/**
-	 * Constant copied from org.eclipse.compare.structuremergeviewer.Differencer.DELETION
-	 * in order to avoid UI dependencies introduced by the org.eclipse.compare bundle
-	 */
-	public static final int DELETION = 2;
-
-	/**
-	 * Constant copied from org.eclipse.compare.structuremergeviewer.Differencer.CHANGE
-	 * in order to avoid UI dependencies introduced by the org.eclipse.compare bundle
-	 */
-	public static final int CHANGE = 3;
-
-	/**
-	 * Constant copied from org.eclipse.compare.structuremergeviewer.Differencer.LEFT
-	 * in order to avoid UI dependencies introduced by the org.eclipse.compare bundle
-	 */
-	public static final int LEFT = 4;
-
-	/**
-	 * Constant copied from org.eclipse.compare.structuremergeviewer.Differencer.RIGHT
-	 * in order to avoid UI dependencies introduced by the org.eclipse.compare bundle
-	 */
-	public static final int RIGHT = 8;
-
-	/**
-	 * Corresponds to {@link RevCommit} object, but contains only those data
-	 * that are required by Synchronize view Change Set
-	 */
-	public static class Commit {
-		private int direction;
-
-		private String shortMessage;
-
-		private AbbreviatedObjectId commitId;
-
-		private Date commitDate;
-
-		private String authorName;
-
-		private String committerName;
-
-		private Map<String, Change> children;
-
-		private Commit() {
-			// reduce the visibility of the default constructor
-		}
-
-		/**
-		 * Indicates if this commit is incoming or outgoing. Returned value
-		 * corresponds to org.eclipse.compare.structuremergeviewer.Differencer#LEFT for incoming and
-		 * org.eclipse.compare.structuremergeviewer.Differencer#RIGHT for outgoing changes
-		 *
-		 * @return change direction
-		 */
-		public int getDirection() {
-			return direction;
-		}
-
-		/**
-		 * @return commit id
-		 */
-		public AbbreviatedObjectId getId() {
-			return commitId;
-		}
-
-		/**
-		 * @return commit author
-		 */
-		public String getAuthorName() {
-			return authorName;
-		}
-
-		/**
-		 * @return the committer name
-		 */
-		public String getCommitterName() {
-			return committerName;
-		}
-
-		/**
-		 * @return commit date
-		 */
-		public Date getCommitDate() {
-			return commitDate;
-		}
-
-		/**
-		 * @return commit short message
-		 */
-		public String getShortMessage() {
-			return shortMessage;
-		}
-
-		/**
-		 * @return list of changes made by this commit or {@code null} when
-		 *         commit doesn't have any changes
-		 */
-		public Map<String, Change> getChildren() {
-			return children;
-		}
-
-		/**
-		 * Disposes nested resources
-		 */
-		public void dispose() {
-			children.clear();
-		}
-
-	}
-
-	/**
-	 * Describes single tree or blob change in commit.
-	 */
-	public static class Change {
-		int kind;
-
-		String name;
-
-		AbbreviatedObjectId objectId;
-
-		AbbreviatedObjectId commitId;
-
-		AbbreviatedObjectId remoteCommitId;
-
-		AbbreviatedObjectId remoteObjectId;
-
-		Change() {
-			// reduce the visibility of the default constructor
-		}
-
-		/**
-		 * Describes if this change is incoming/outgoing addition, deletion or
-		 * change.
-		 *
-		 * It uses static values of LEFT, RIGHT, ADDITION, DELETION, CHANGE from
-		 * org.eclipse.compare.structuremergeviewer.Differencer class.
-		 *
-		 * @return kind
-		 */
-		public int getKind() {
-			return kind;
-		}
-
-		/**
-		 * @return object name
-		 */
-		public String getName() {
-			return name;
-		}
-
-		/**
-		 * @return id of commit containing this change
-		 */
-		public AbbreviatedObjectId getCommitId() {
-			return commitId;
-		}
-
-		/**
-		 * @return id of parent commit
-		 */
-		public AbbreviatedObjectId getRemoteCommitId() {
-			return remoteCommitId;
-		}
-
-		/**
-		 * @return object id
-		 */
-		public AbbreviatedObjectId getObjectId() {
-			return objectId;
-		}
-
-		/**
-		 * @return remote object id
-		 */
-		public AbbreviatedObjectId getRemoteObjectId() {
-			return remoteObjectId;
-		}
-
-		@Override
-		public int hashCode() {
-			final int prime = 31;
-			int result = 1;
-			result = prime * result
-					+ ((objectId == null) ? 0 : objectId.hashCode());
-			result = prime
-					* result
-					+ ((remoteObjectId == null) ? 0 : remoteObjectId.hashCode());
-			return result;
-		}
-
-		@Override
-		public boolean equals(Object obj) {
-			if (this == obj)
-				return true;
-			if (obj == null)
-				return false;
-			if (getClass() != obj.getClass())
-				return false;
-			Change other = (Change) obj;
-			if (objectId == null) {
-				if (other.objectId != null)
-					return false;
-			} else if (!objectId.equals(other.objectId))
-				return false;
-			if (remoteObjectId == null) {
-				if (other.remoteObjectId != null)
-					return false;
-			} else if (!remoteObjectId.equals(other.remoteObjectId))
-				return false;
-			return true;
-		}
-
-		@Override
-		public String toString() {
-			StringBuilder change = new StringBuilder("Change("); //$NON-NLS-1$
-			if ((kind & LEFT) != 0)
-				change.append("OUTGOING "); //$NON-NLS-1$
-			else
-				// should be RIGHT
-				change.append("INCOMING "); //$NON-NLS-1$
-			if ((kind & ADDITION) != 0)
-				change.append("ADDITION "); //$NON-NLS-1$
-			else if ((kind & DELETION) != 0)
-				change.append("DELETION "); //$NON-NLS-1$
-			else
-				// should be CHANGE
-				change.append("CHANGE "); //$NON-NLS-1$
-
-			change.append(name);
-			change.append(";\n\tcurrent objectId: "); //$NON-NLS-1$
-			change.append(getObjectId(objectId));
-			change.append(";\n\tparent objectId: "); //$NON-NLS-1$
-			change.append(getObjectId(remoteObjectId));
-			change.append(";\n\tcurrent commit: "); //$NON-NLS-1$
-			change.append(getObjectId(commitId));
-			change.append(";\n\tparent commit: "); //$NON-NLS-1$
-			change.append(getObjectId(remoteCommitId));
-			change.append("\n)"); //$NON-NLS-1$
-
-			return change.toString();
-		}
-
-		private String getObjectId(AbbreviatedObjectId object) {
-			if (object != null)
-				return object.toObjectId().getName();
-			else
-				return ObjectId.zeroId().getName();
-		}
-
-	}
-
-	static final AbbreviatedObjectId ZERO_ID = AbbreviatedObjectId
-			.fromObjectId(zeroId());
-
-	/**
-	 * Scans given {@code repo} and build list of commits between two given
-	 * RevCommit objectId's. Each commit contains list of changed resources
-	 *
-	 * @param repo
-	 *            repository that should be scanned
-	 * @param srcId
-	 *            RevCommit id that git history traverse will start from
-	 * @param dstId
-	 *            RevCommit id that git history traverse will end
-	 * @param pathFilter
-	 *            path filter definition or {@code null} when all paths should
-	 *            be included
-	 * @return list of {@link Commit} object's between {@code srcId} and
-	 *         {@code dstId}
-	 * @throws IOException
-	 */
-	public static List<Commit> build(Repository repo, ObjectId srcId,
-			ObjectId dstId, TreeFilter pathFilter) throws IOException {
-		if (dstId.equals(srcId))
-			return new ArrayList<Commit>(0);
-
-		final RevWalk rw = new RevWalk(repo);
-
-		final RevFlag localFlag = rw.newFlag("local"); //$NON-NLS-1$
-		final RevFlag remoteFlag = rw.newFlag("remote"); //$NON-NLS-1$
-		final RevFlagSet allFlags = new RevFlagSet();
-		allFlags.add(localFlag);
-		allFlags.add(remoteFlag);
-		rw.carry(allFlags);
-
-		RevCommit srcCommit = rw.parseCommit(srcId);
-		srcCommit.add(localFlag);
-		rw.markStart(srcCommit);
-		srcCommit = null; // free not needed resources
-
-		RevCommit dstCommit = rw.parseCommit(dstId);
-		dstCommit.add(remoteFlag);
-		rw.markStart(dstCommit);
-		dstCommit = null; // free not needed resources
-
-		if (pathFilter != null)
-			rw.setTreeFilter(pathFilter);
-
-		List<Commit> result = new ArrayList<Commit>();
-		for (RevCommit revCommit : rw) {
-			if (revCommit.hasAll(allFlags))
-				break;
-
-			Commit commit = new Commit();
-			commit.shortMessage = revCommit.getShortMessage();
-			commit.commitId = AbbreviatedObjectId.fromObjectId(revCommit);
-			commit.authorName = revCommit.getAuthorIdent().getName();
-			commit.committerName = revCommit.getCommitterIdent().getName();
-			commit.commitDate = revCommit.getAuthorIdent().getWhen();
-
-			RevCommit actualCommit, parentCommit;
-			if (revCommit.has(localFlag)) {
-				actualCommit = revCommit;
-				parentCommit = getParentCommit(revCommit);
-				commit.direction = RIGHT;
-			} else if (revCommit.has(remoteFlag)) {
-				actualCommit = getParentCommit(revCommit);
-				parentCommit = revCommit;
-				commit.direction = LEFT;
-			} else
-				throw new GitCommitsModelDirectionException();
-
-			commit.children = getChangedObjects(repo, actualCommit,
-					parentCommit, pathFilter, commit.direction);
-
-			if (commit.children != null)
-				result.add(commit);
-		}
-		rw.dispose();
-
-		return result;
-	}
-
-	private static RevCommit getParentCommit(RevCommit commit) {
-		if (commit.getParents().length > 0)
-			return commit.getParents()[0];
-		else
-			return null;
-	}
-
-	private static Map<String, Change> getChangedObjects(Repository repo,
-			RevCommit parentCommit, RevCommit remoteCommit,
-			TreeFilter pathFilter, final int direction) throws IOException {
-		final TreeWalk tw = new TreeWalk(repo);
-		addTreeFilter(tw, parentCommit);
-		addTreeFilter(tw, remoteCommit);
-
-		tw.setRecursive(true);
-		if (pathFilter == null)
-			tw.setFilter(ANY_DIFF);
-		else
-			tw.setFilter(AndTreeFilter.create(ANY_DIFF, pathFilter));
-
-		final int localTreeId = direction == LEFT ? 1 : 0;
-		final int remoteTreeId = direction == LEFT ? 0 : 1;
-		final Map<String, Change> result = new HashMap<String, GitCommitsModelCache.Change>();
-		final AbbreviatedObjectId actualCommit = getAbbreviatedObjectId(parentCommit);
-		final AbbreviatedObjectId remoteCommitAbb = getAbbreviatedObjectId(remoteCommit);
-
-		MutableObjectId idBuf = new MutableObjectId();
-		while (tw.next()) {
-			Change change = new Change();
-			change.commitId = actualCommit;
-			change.remoteCommitId = remoteCommitAbb;
-			change.name = tw.getNameString();
-			tw.getObjectId(idBuf, localTreeId);
-			change.objectId = AbbreviatedObjectId.fromObjectId(idBuf);
-			tw.getObjectId(idBuf, remoteTreeId);
-			change.remoteObjectId = AbbreviatedObjectId.fromObjectId(idBuf);
-
-			calculateAndSetChangeKind(direction, change);
-
-			result.put(tw.getPathString(), change);
-		}
-		tw.release();
-
-		return result.size() > 0 ? result : null;
-	}
-
-	private static void addTreeFilter(TreeWalk tw, RevCommit commit)
-			throws IOException {
-		if (commit != null)
-			tw.addTree(commit.getTree());
-		else
-			tw.addTree(new EmptyTreeIterator());
-	}
-
-	private static AbbreviatedObjectId getAbbreviatedObjectId(RevCommit commit) {
-		if (commit != null)
-			return AbbreviatedObjectId.fromObjectId(commit);
-		else
-			return ZERO_ID;
-	}
-
-	static void calculateAndSetChangeKind(final int direction, Change change) {
-		if (ZERO_ID.equals(change.objectId)) { // missing locally
-			change.objectId = null; // clear zero id;
-			if (direction == LEFT)
-				change.kind = direction | ADDITION;
-			else // should be Differencer.RIGHT
-				change.kind = direction | DELETION;
-		} else if (ZERO_ID.equals(change.remoteObjectId)) { // missing remotely
-			change.remoteObjectId = null; // clear zero id;
-			if (direction == LEFT)
-				change.kind = direction | DELETION;
-			else // should be Differencer.RIGHT
-				change.kind = direction | ADDITION;
-		} else
-			change.kind = direction | CHANGE;
-	}
-
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitCommitsModelDirectionException.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitCommitsModelDirectionException.java
deleted file mode 100644
index cf38296..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitCommitsModelDirectionException.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2012, Dariusz Luksza <dariusz@luksza.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.synchronize;
-
-/**
- * Thrown when commit direction can't be determined during
- * {@link GitCommitsModelCache#build(org.eclipse.jgit.lib.Repository, org.eclipse.jgit.lib.ObjectId, org.eclipse.jgit.lib.ObjectId, org.eclipse.jgit.treewalk.filter.TreeFilter)}
- */
-public class GitCommitsModelDirectionException extends RuntimeException {
-
-	/**
-	 *
-	 */
-	private static final long serialVersionUID = 7867729888561453855L;
-
-	/**
-	 * Creates exception instance with default message
-	 */
-	public GitCommitsModelDirectionException() {
-		super("Unknown commit direction"); //$NON-NLS-1$
-	}
-
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitRemoteFile.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitRemoteFile.java
deleted file mode 100644
index 87d74e7..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitRemoteFile.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2011, Dariusz Luksza <dariusz@luksza.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.synchronize;
-
-import org.eclipse.core.resources.IStorage;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.internal.storage.CommitBlobStorage;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.team.core.TeamException;
-
-class GitRemoteFile extends GitRemoteResource {
-
-	private final Repository repo;
-
-	GitRemoteFile(Repository repo, RevCommit commitId, ObjectId objectId,
-			String path) {
-		super(commitId, objectId, path);
-		this.repo = repo;
-	}
-
-	public boolean isContainer() {
-		return false;
-	}
-
-	@Override
-	protected void fetchContents(IProgressMonitor monitor) throws TeamException {
-		CommitBlobStorage content = new CommitBlobStorage(repo, getPath(),
-				getObjectId(), getCommitId());
-		try {
-			setContents(content.getContents(), monitor);
-		} catch (CoreException e) {
-			Activator.error("", e); //$NON-NLS-1$
-		}
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (obj == this)
-			return true;
-
-		if (obj instanceof GitRemoteFile) {
-			GitRemoteFile that = (GitRemoteFile) obj;
-
-			return getPath().equals(that.getPath())
-					&& getObjectId().equals(that.getObjectId());
-		}
-
-		return false;
-	}
-
-	@Override
-	public IStorage getStorage(IProgressMonitor monitor) throws TeamException {
-		return new CommitBlobStorage(repo, getCachePath(), getObjectId(),
-				getCommitId());
-	}
-
-	@Override
-	public int hashCode() {
-		return getObjectId().hashCode() ^ getPath().hashCode();
-	}
-
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitRemoteFolder.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitRemoteFolder.java
deleted file mode 100644
index 465a723..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitRemoteFolder.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2011, Dariusz Luksza <dariusz@luksza.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.synchronize;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.egit.core.CoreText;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.osgi.util.NLS;
-import org.eclipse.team.core.TeamException;
-import org.eclipse.team.core.variants.IResourceVariant;
-
-class GitRemoteFolder extends GitRemoteResource {
-
-	private final GitSyncObjectCache cachedData;
-	private final Repository repo;
-
-	/**
-	 *
-	 * @param repo
-	 * @param cachedData
-	 * @param commitId
-	 * @param objectId
-	 *            given object sha-1 id or {@code null} if this object doesn't
-	 *            exist in remote
-	 * @param path
-	 */
-	GitRemoteFolder(Repository repo, GitSyncObjectCache cachedData,
-			RevCommit commitId, ObjectId objectId, String path) {
-		super(commitId, objectId, path);
-		this.repo = repo;
-		this.cachedData = cachedData;
-	}
-
-	public boolean isContainer() {
-		return true;
-	}
-
-	@Override
-	protected void fetchContents(IProgressMonitor monitor) throws TeamException {
-		// should be never used on folder
-	}
-
-	public boolean equals(Object object) {
-		if (object == this)
-			return true;
-
-		if (object instanceof GitRemoteFolder) {
-			GitRemoteFolder that = (GitRemoteFolder) object;
-
-			return getPath().equals(that.getPath())
-					&& getObjectId().equals(that.getObjectId());
-		}
-
-		return false;
-	}
-
-	public int hashCode() {
-		return getObjectId().hashCode() ^ getPath().hashCode();
-	}
-
-	GitRemoteResource[] members(IProgressMonitor monitor) {
-		Collection<GitSyncObjectCache> members = cachedData.members();
-		if (members == null || members.size() == 0)
-			return new GitRemoteResource[0];
-
-		List<IResourceVariant> result = new ArrayList<IResourceVariant>();
-
-		monitor.beginTask(
-				NLS.bind(CoreText.GitRemoteFolder_fetchingMembers, getPath()),
-				cachedData.membersCount());
-		try {
-			for (GitSyncObjectCache member : members) {
-				ThreeWayDiffEntry diffEntry = member.getDiffEntry();
-				String memberPath = diffEntry.getPath();
-
-				GitRemoteResource obj;
-				ObjectId id = diffEntry.getRemoteId().toObjectId();
-				if (diffEntry.isTree())
-					obj = new GitRemoteFolder(repo, member, getCommitId(), id,
-							memberPath);
-				else
-					obj = new GitRemoteFile(repo, getCommitId(), id, memberPath);
-
-				result.add(obj);
-				monitor.worked(1);
-			}
-		} finally {
-			monitor.done();
-		}
-
-		return result.toArray(new GitRemoteResource[result.size()]);
-	}
-
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitRemoteResource.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitRemoteResource.java
deleted file mode 100644
index e8da1ee..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitRemoteResource.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2011, 2012 Dariusz Luksza <dariusz@luksza.org> and others.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.synchronize;
-
-import static org.eclipse.jgit.lib.ObjectId.zeroId;
-
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.PersonIdent;
-import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.team.core.variants.CachedResourceVariant;
-
-abstract class GitRemoteResource extends CachedResourceVariant {
-
-	private final String path;
-
-	private final RevCommit commitId;
-
-	private final ObjectId objectId;
-
-
-	GitRemoteResource(RevCommit commitId, ObjectId objectId, String path) {
-		this.path = path;
-		this.objectId = objectId;
-		this.commitId = commitId;
-	}
-
-	public String getName() {
-		int lastSeparator = path.lastIndexOf("/"); //$NON-NLS-1$
-		return path.substring(lastSeparator + 1, path.length());
-	}
-
-	public String getContentIdentifier() {
-		if (commitId == null)
-			return ""; //$NON-NLS-1$
-
-		StringBuilder s = new StringBuilder();
-		s.append(commitId.abbreviate(7).name());
-		s.append("..."); //$NON-NLS-1$
-
-		PersonIdent authorIdent = commitId.getAuthorIdent();
-		if (authorIdent != null) {
-			s.append(" ("); //$NON-NLS-1$
-			s.append(authorIdent.getName());
-			s.append(")"); //$NON-NLS-1$
-		}
-		return s.toString();
-	}
-
-	public byte[] asBytes() {
-		return getObjectId().name().getBytes();
-	}
-
-	@Override
-	protected String getCachePath() {
-		return path;
-	}
-
-	@Override
-	protected String getCacheId() {
-		return "org.eclipse.egit"; //$NON-NLS-1$
-	}
-
-	boolean exists() {
-		return commitId != null;
-	}
-
-	RevCommit getCommitId() {
-		return commitId;
-	}
-
-	/**
-	 * @return object id, or {code {@link RevCommit#zeroId()} if object doesn't
-	 *         exist in repository
-	 */
-	ObjectId getObjectId() {
-		return objectId != null ? objectId : zeroId();
-	}
-
-	String getPath() {
-		return path;
-	}
-
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitRemoteResourceVariantTree.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitRemoteResourceVariantTree.java
deleted file mode 100644
index 6343054..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitRemoteResourceVariantTree.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     IBM Corporation - initial API and implementation
- *     Dariusz Luksza <dariusz@luksza.org>
- *******************************************************************************/
-package org.eclipse.egit.core.synchronize;
-
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.team.core.variants.SessionResourceVariantByteStore;
-
-class GitRemoteResourceVariantTree extends GitResourceVariantTree {
-
-	GitRemoteResourceVariantTree(GitSyncCache cache, GitSynchronizeDataSet data) {
-		super(new SessionResourceVariantByteStore(), cache, data);
-	}
-
-	@Override
-	protected ObjectId getObjectId(ThreeWayDiffEntry diffEntry) {
-		return diffEntry.getRemoteId().toObjectId();
-	}
-
-	@Override
-	protected RevCommit getCommitId(GitSynchronizeData gsd) {
-		return gsd.getSrcRevCommit();
-	}
-
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitResourceVariantComparator.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitResourceVariantComparator.java
deleted file mode 100644
index c3266b8..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitResourceVariantComparator.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010, 2012 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     IBM Corporation - initial API and implementation
- *     Dariusz Luksza <dariusz@luksza.org>
- *     Daniel Megert <daniel_megert@ch.ibm.com> - remove unnecessary @SuppressWarnings
- *******************************************************************************/
-package org.eclipse.egit.core.synchronize;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Arrays;
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
-import org.eclipse.team.core.TeamException;
-import org.eclipse.team.core.variants.IResourceVariant;
-import org.eclipse.team.core.variants.IResourceVariantComparator;
-
-class GitResourceVariantComparator implements IResourceVariantComparator {
-
-	private final GitSynchronizeDataSet gsd;
-
-	GitResourceVariantComparator(GitSynchronizeDataSet dataSet) {
-		gsd = dataSet;
-	}
-
-	@SuppressWarnings("resource")
-	public boolean compare(IResource local, IResourceVariant remote) {
-		if (!local.exists() || remote == null) {
-			return false;
-		}
-
-		if (local instanceof IFile) {
-			if (remote.isContainer()) {
-				return false;
-			}
-
-			InputStream stream = null;
-			InputStream remoteStream = null;
-			try {
-				remoteStream = remote.getStorage(new NullProgressMonitor())
-						.getContents();
-				stream = getLocal(local);
-				byte[] remoteBytes = new byte[8096];
-				byte[] bytes = new byte[8096];
-
-				int remoteRead = remoteStream.read(remoteBytes);
-				int read = stream.read(bytes);
-				if (remoteRead != read) {
-					return false;
-				}
-
-				while (Arrays.equals(bytes, remoteBytes)) {
-					remoteRead = remoteStream.read(remoteBytes);
-					read = stream.read(bytes);
-					if (remoteRead != read) {
-						// didn't read the same amount, it's uneven
-						return false;
-					} else if (read == -1) {
-						// both at EOF, check their contents
-						return Arrays.equals(bytes, remoteBytes);
-					}
-				}
-			} catch (IOException e) {
-				logException(e);
-				return false;
-			} catch (CoreException e) {
-				logException(e);
-				return false;
-			} finally {
-				closeStream(stream);
-				closeStream(remoteStream);
-			}
-		} else if (local instanceof IContainer) {
-			GitRemoteFolder gitVariant = (GitRemoteFolder) remote;
-			if (!remote.isContainer() || (local.exists() ^ gitVariant.exists()))
-				return false;
-
-			return local.getLocation().toString().equals(gitVariant.getCachePath());
-		}
-		return false;
-	}
-
-	public boolean compare(IResourceVariant base, IResourceVariant remote) {
-		GitRemoteResource gitBase = (GitRemoteResource) base;
-		GitRemoteResource gitRemote = (GitRemoteResource) remote;
-
-		boolean exists = gitBase.exists() && gitRemote.exists();
-		boolean equalType = !(gitBase.isContainer() ^ gitRemote.isContainer());
-		boolean equalSha1 = gitBase.getObjectId().getName()
-				.equals(gitRemote.getObjectId().getName());
-
-		return equalType && exists && equalSha1;
-	}
-
-	public boolean isThreeWay() {
-		return true;
-	}
-
-	private InputStream getLocal(IResource resource) throws CoreException {
-		if (gsd.getData(resource.getProject().getName()).shouldIncludeLocal())
-			return getSynchronizedFile(resource).getContents();
-		else
-			try {
-				if (resource.getType() == IResource.FILE)
-					return getSynchronizedFile(resource).getContents();
-				else
-					return new ByteArrayInputStream(new byte[0]);
-			} catch (TeamException e) {
-				throw new CoreException(e.getStatus());
-			}
-	}
-
-	private IFile getSynchronizedFile(IResource resource) throws CoreException {
-		IFile file = ((IFile) resource);
-		if (!file.isSynchronized(0))
-			file.refreshLocal(0, null);
-
-		return file;
-	}
-
-	private void logException(Exception e) {
-		IStatus error = new Status(IStatus.ERROR, Activator.getPluginId(),
-				e.getMessage(), e);
-		Activator.getDefault().getLog().log(error);
-	}
-
-	private void closeStream(InputStream stream) {
-		if (stream != null) {
-			try {
-				stream.close();
-			} catch (IOException e) {
-				logException(e);
-			}
-		}
-	}
-
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitResourceVariantTree.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitResourceVariantTree.java
deleted file mode 100644
index 189604d..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitResourceVariantTree.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     IBM Corporation - initial API and implementation
- *     Dariusz Luksza <dariusz@luksza.org>
- *******************************************************************************/
-package org.eclipse.egit.core.synchronize;
-
-import static org.eclipse.egit.core.internal.util.ResourceUtil.isNonWorkspace;
-import static org.eclipse.jgit.lib.ObjectId.zeroId;
-import static org.eclipse.jgit.lib.Repository.stripWorkDir;
-
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.WeakHashMap;
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.SubMonitor;
-import org.eclipse.egit.core.CoreText;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.osgi.util.NLS;
-import org.eclipse.team.core.TeamException;
-import org.eclipse.team.core.variants.IResourceVariant;
-import org.eclipse.team.core.variants.ResourceVariantByteStore;
-import org.eclipse.team.core.variants.ResourceVariantTree;
-
-abstract class GitResourceVariantTree extends ResourceVariantTree {
-
-	private final GitSyncCache gitCache;
-
-	private final GitSynchronizeDataSet gsds;
-
-	private final Map<IResource, IResourceVariant> cache = new WeakHashMap<IResource, IResourceVariant>();
-
-
-	GitResourceVariantTree(ResourceVariantByteStore store,
-			GitSyncCache gitCache, GitSynchronizeDataSet gsds) {
-		super(store);
-		this.gsds = gsds;
-		this.gitCache = gitCache;
-	}
-
-	public IResource[] roots() {
-		Set<IResource> roots = new HashSet<IResource>();
-		for (GitSynchronizeData gsd : gsds)
-			if (gsd.getPathFilter() == null)
-				roots.addAll(gsd.getProjects());
-			else
-				for (IContainer container : gsd.getIncludedPaths())
-					roots.add(container.getProject());
-
-		return roots.toArray(new IResource[roots.size()]);
-	}
-
-	/**
-	 * Disposes all nested resources
-	 */
-	public void dispose() {
-		if (gsds != null)
-			gsds.dispose();
-
-		cache.clear();
-	}
-
-	@Override
-	protected IResourceVariant fetchVariant(IResource resource, int depth,
-			IProgressMonitor monitor) throws TeamException {
-		SubMonitor subMonitor = SubMonitor.convert(monitor);
-		if (resource == null || isNonWorkspace(resource)) {
-			subMonitor.done();
-			return null;
-		}
-
-		subMonitor.beginTask(NLS.bind(
-				CoreText.GitResourceVariantTree_fetchingVariant,
-				resource.getName()), IProgressMonitor.UNKNOWN);
-		try {
-			return fetchVariant(resource);
-		} finally {
-			subMonitor.done();
-		}
-	}
-
-	private IResourceVariant fetchVariant(IResource resource) {
-		if (gitCache == null)
-			return null;
-
-		if (cache.containsKey(resource))
-			return cache.get(resource);
-
-		GitSynchronizeData gsd = gsds.getData(resource.getProject());
-		if (gsd == null)
-			return null;
-
-		Repository repo = gsd.getRepository();
-		String path = getPath(resource, repo);
-
-		GitSyncObjectCache syncCache = gitCache.get(repo);
-		GitSyncObjectCache cachedData = syncCache.get(path);
-		if (cachedData == null)
-			return null;
-
-		IResourceVariant variant = null;
-		ObjectId objectId = getObjectId(cachedData.getDiffEntry());
-		if (!objectId.equals(zeroId())) {
-			if (resource.getType() == IResource.FILE)
-				variant = new GitRemoteFile(repo, getCommitId(gsd), objectId,
-						path);
-			else
-				variant = new GitRemoteFolder(repo, cachedData,
-						getCommitId(gsd), objectId, path);
-
-			cache.put(resource, variant);
-		}
-
-		return variant;
-	}
-
-	protected abstract ObjectId getObjectId(ThreeWayDiffEntry diffEntry);
-
-	protected abstract RevCommit getCommitId(GitSynchronizeData gsd);
-
-	@Override
-	protected IResourceVariant[] fetchMembers(IResourceVariant variant,
-			IProgressMonitor progress) throws TeamException {
-		if (variant == null || !(variant instanceof GitRemoteFolder))
-			return new IResourceVariant[0];
-
-		GitRemoteFolder gitVariant = (GitRemoteFolder) variant;
-
-		try {
-			return gitVariant.members(progress);
-		} finally {
-			progress.done();
-		}
-	}
-
-	public IResourceVariant getResourceVariant(final IResource resource)
-			throws TeamException {
-		return fetchVariant(resource, 0, null);
-	}
-
-	private String getPath(final IResource resource, Repository repo) {
-		return stripWorkDir(repo.getWorkTree(), resource.getLocation().toFile());
-	}
-
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitResourceVariantTreeSubscriber.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitResourceVariantTreeSubscriber.java
deleted file mode 100644
index dee4c3d..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitResourceVariantTreeSubscriber.java
+++ /dev/null
@@ -1,279 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010-2012 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     IBM Corporation - initial API and implementation
- *     Dariusz Luksza <dariusz@luksza.org>
- *     François Rey - gracefully ignore linked resources
- *******************************************************************************/
-package org.eclipse.egit.core.synchronize;
-
-import static org.eclipse.jgit.lib.Repository.stripWorkDir;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.egit.core.CoreText;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.treewalk.TreeWalk;
-import org.eclipse.team.core.TeamException;
-import org.eclipse.team.core.synchronize.SyncInfo;
-import org.eclipse.team.core.variants.IResourceVariant;
-import org.eclipse.team.core.variants.IResourceVariantComparator;
-import org.eclipse.team.core.variants.IResourceVariantTree;
-import org.eclipse.team.core.variants.ResourceVariantTreeSubscriber;
-
-/**
- *
- */
-public class GitResourceVariantTreeSubscriber extends
-		ResourceVariantTreeSubscriber {
-
-	/**
-	 * A resource variant tree of the remote branch(es).
-	 */
-	private GitRemoteResourceVariantTree remoteTree;
-
-	/**
-	 * A resource variant tree against HEAD.
-	 */
-	private GitBaseResourceVariantTree baseTree;
-
-	private GitSynchronizeDataSet gsds;
-
-	private IResource[] roots;
-
-	private GitSyncCache cache;
-
-	/**
-	 * @param data
-	 */
-	public GitResourceVariantTreeSubscriber(GitSynchronizeDataSet data) {
-		this.gsds = data;
-	}
-
-	/**
-	 * Initialize git subscriber. This method will pre-fetch data from git
-	 * repository. This approach will reduce number of {@link TreeWalk}'s
-	 * created during synchronization
-	 *
-	 * @param monitor
-	 */
-	public void init(IProgressMonitor monitor) {
-		monitor.beginTask(
-				CoreText.GitResourceVariantTreeSubscriber_fetchTaskName,
-				gsds.size());
-		try {
-			cache = GitSyncCache.getAllData(gsds, monitor);
-		} finally {
-			monitor.done();
-		}
-	}
-
-	@Override
-	public boolean isSupervised(IResource res) throws TeamException {
-		return IResource.FILE == res.getType()
-				&& gsds.contains(res.getProject()) && shouldBeIncluded(res);
-	}
-
-	/**
-	 * Returns all members of git repository (including those that are not
-	 * imported into workspace)
-	 *
-	 * @param res
-	 */
-	@Override
-	public IResource[] members(IResource res) throws TeamException {
-		if(res.getType() == IResource.FILE || !shouldBeIncluded(res))
-			return new IResource[0];
-
-		GitSynchronizeData gsd = gsds.getData(res.getProject());
-		Repository repo = gsd.getRepository();
-		GitSyncObjectCache repoCache = cache.get(repo);
-
-		Set<IResource> gitMembers = new HashSet<IResource>();
-		Map<String, IResource> allMembers = new HashMap<String, IResource>();
-
-		Set<GitSyncObjectCache> gitCachedMembers = new HashSet<GitSyncObjectCache>();
-		String path = stripWorkDir(repo.getWorkTree(), res.getLocation().toFile());
-		GitSyncObjectCache cachedMembers = repoCache.get(path);
-		if (cachedMembers != null) {
-			Collection<GitSyncObjectCache> members = cachedMembers.members();
-			if (members != null)
-				gitCachedMembers.addAll(members);
-		}
-		try {
-			for (IResource member : ((IContainer) res).members())
-				allMembers.put(member.getName(), member);
-
-			for (GitSyncObjectCache gitMember : gitCachedMembers) {
-				IResource member = allMembers.get(gitMember.getName());
-				if (member != null)
-					gitMembers.add(member);
-			}
-		} catch (CoreException e) {
-			throw TeamException.asTeamException(e);
-		}
-
-		return gitMembers.toArray(new IResource[gitMembers.size()]);
-	}
-
-	@Override
-	public void refresh(IResource[] resources, int depth,
-			IProgressMonitor monitor) throws TeamException {
-		for (IResource resource : resources) {
-			// check to see if there is a full refresh
-			if (resource.getType() == IResource.ROOT) {
-				// refresh entire cache
-				GitSyncCache newCache = GitSyncCache.getAllData(gsds, monitor);
-				cache.merge(newCache);
-				super.refresh(resources, depth, monitor);
-				return;
-			}
-		}
-
-		// not refreshing the workspace, locate and collect target resources
-		Map<GitSynchronizeData, Collection<String>> updateRequests = new HashMap<GitSynchronizeData, Collection<String>>();
-		for (IResource resource : resources) {
-			IProject project = resource.getProject();
-			GitSynchronizeData data = gsds.getData(project.getName());
-			if (data != null) {
-				RepositoryMapping mapping = RepositoryMapping
-						.getMapping(project);
-				// mapping may be null if the project has been closed
-				if (mapping != null) {
-					Collection<String> paths = updateRequests.get(data);
-					if (paths == null) {
-						paths = new ArrayList<String>();
-						updateRequests.put(data, paths);
-					}
-
-					String path = mapping.getRepoRelativePath(resource);
-					// null path may be returned, check for this
-					if (path == null)
-						// unknown, force a refresh of the whole repository
-						path = ""; //$NON-NLS-1$
-					paths.add(path);
-				}
-			}
-		}
-
-		// scan only the repositories that were affected
-		if (!updateRequests.isEmpty()) {
-			// refresh cache
-			GitSyncCache newCache = GitSyncCache.getAllData(updateRequests,
-					monitor);
-			cache.merge(newCache);
-		}
-
-		super.refresh(resources, depth, monitor);
-	}
-
-	@Override
-	public IResource[] roots() {
-		if (roots == null)
-			roots = gsds.getAllProjects();
-		IResource[] result = new IResource[roots.length];
-		System.arraycopy(roots, 0, result, 0, roots.length);
-		return result;
-	}
-
-	/**
-	 * @param data
-	 */
-	public void reset(GitSynchronizeDataSet data) {
-		gsds = data;
-
-		roots = null;
-		baseTree = null;
-		remoteTree = null;
-	}
-
-	/**
-	 * Disposes nested resources
-	 */
-	public void dispose() {
-		if (baseTree != null)
-			baseTree.dispose();
-		if (remoteTree != null)
-			remoteTree.dispose();
-		gsds.dispose();
-	}
-
-	@Override
-	public String getName() {
-		return CoreText.GitBranchResourceVariantTreeSubscriber_gitRepository;
-	}
-
-	@Override
-	public IResourceVariantComparator getResourceComparator() {
-		return new GitResourceVariantComparator(gsds);
-	}
-
-	@Override
-	protected IResourceVariantTree getBaseTree() {
-		if (baseTree == null)
-			baseTree = new GitBaseResourceVariantTree(cache, gsds);
-
-		return baseTree;
-	}
-
-	@Override
-	protected IResourceVariantTree getRemoteTree() {
-		if (remoteTree == null)
-			remoteTree = new GitRemoteResourceVariantTree(cache, gsds);
-
-		return remoteTree;
-	}
-
-	@Override
-	protected SyncInfo getSyncInfo(IResource local, IResourceVariant base,
-			IResourceVariant remote) throws TeamException {
-
-		Repository repo = gsds.getData(local.getProject()).getRepository();
-		SyncInfo info = new GitSyncInfo(local, base, remote,
-				getResourceComparator(), cache.get(repo), repo);
-
-		info.init();
-		return info;
-	}
-
-	private boolean shouldBeIncluded(IResource res) {
-		if (res == null || res.isLinked(IResource.CHECK_ANCESTORS))
-			return false;
-		final IProject proj = res.getProject();
-		if (proj == null)
-			return false;
-		final GitSynchronizeData d = gsds.getData(proj);
-		if (d == null)
-			return false;
-		final Set<IContainer> includedPaths = d.getIncludedPaths();
-		if (includedPaths == null)
-			return true;
-
-		IPath path = res.getLocation();
-		for (IContainer container : includedPaths)
-			if (container.getLocation().isPrefixOf(path))
-				return true;
-
-		return false;
-	}
-
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitSubscriberMergeContext.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitSubscriberMergeContext.java
deleted file mode 100644
index 9683234..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitSubscriberMergeContext.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2010, 2013 Dariusz Luksza <dariusz@luksza.org> and others.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.synchronize;
-
-import java.io.IOException;
-import java.util.Collection;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IResourceChangeEvent;
-import org.eclipse.core.resources.IResourceChangeListener;
-import org.eclipse.core.resources.IResourceDelta;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.resources.mapping.ResourceTraversal;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.CoreText;
-import org.eclipse.egit.core.internal.indexdiff.GitResourceDeltaVisitor;
-import org.eclipse.egit.core.internal.indexdiff.IndexDiffCache;
-import org.eclipse.egit.core.internal.indexdiff.IndexDiffChangedListener;
-import org.eclipse.egit.core.internal.indexdiff.IndexDiffData;
-import org.eclipse.egit.core.op.AddToIndexOperation;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.team.core.TeamException;
-import org.eclipse.team.core.diff.IDiff;
-import org.eclipse.team.core.mapping.ISynchronizationScopeManager;
-import org.eclipse.team.core.subscribers.SubscriberMergeContext;
-
-/**
- *
- */
-public class GitSubscriberMergeContext extends SubscriberMergeContext {
-
-	private final GitSynchronizeDataSet gsds;
-
-	private final IndexDiffChangedListener indexChangeListener;
-
-	private final IResourceChangeListener resourceChangeListener;
-
-	private final GitResourceVariantTreeSubscriber subscriber;
-
-	/**
-	 * @param subscriber
-	 * @param manager
-	 * @param gsds
-	 */
-	public GitSubscriberMergeContext(final GitResourceVariantTreeSubscriber subscriber,
-			ISynchronizationScopeManager manager, GitSynchronizeDataSet gsds) {
-		super(subscriber, manager);
-		this.subscriber = subscriber;
-		this.gsds = gsds;
-
-
-		indexChangeListener = new IndexDiffChangedListener() {
-			public void indexDiffChanged(Repository repository,
-					IndexDiffData indexDiffData) {
-				handleRepositoryChange(repository);
-			}
-		};
-		resourceChangeListener = new IResourceChangeListener() {
-
-			public void resourceChanged(IResourceChangeEvent event) {
-				IResourceDelta delta = event.getDelta();
-				if (delta == null)
-					return;
-
-				handleResourceChange(delta);
-			}
-		};
-		IndexDiffCache indexDiffCache = Activator.getDefault().getIndexDiffCache();
-		if (indexDiffCache != null)
-			indexDiffCache.addIndexDiffChangedListener(indexChangeListener);
-
-		ResourcesPlugin.getWorkspace().addResourceChangeListener(resourceChangeListener);
-
-		initialize();
-	}
-
-	public void markAsMerged(IDiff node, boolean inSyncHint,
-			IProgressMonitor monitor) throws CoreException {
-		IResource resource = getDiffTree().getResource(node);
-		AddToIndexOperation operation = new AddToIndexOperation(
-				new IResource[] { resource });
-		operation.execute(monitor);
-	}
-
-	public void reject(IDiff diff, IProgressMonitor monitor)
-			throws CoreException {
-		// TODO Auto-generated method stub
-
-	}
-
-	/**
-	 * @return git synchronization data
-	 */
-	public GitSynchronizeDataSet getSyncData() {
-		return gsds;
-	}
-
-	@Override
-	protected void makeInSync(IDiff diff, IProgressMonitor monitor)
-			throws CoreException {
-		// TODO Auto-generated method stub
-
-	}
-
-	@Override
-	public void dispose() {
-		Activator activator = Activator.getDefault();
-		if (activator == null)
-			return;
-
-		IndexDiffCache indexDiffCache = activator.getIndexDiffCache();
-		if (indexDiffCache != null)
-			indexDiffCache.removeIndexDiffChangedListener(indexChangeListener);
-
-		ResourcesPlugin.getWorkspace().removeResourceChangeListener(resourceChangeListener);
-		subscriber.dispose();
-		super.dispose();
-	}
-
-	private void handleRepositoryChange(Repository which) {
-		boolean shouldRefresh = false;
-		for (GitSynchronizeData gsd : gsds) {
-			if (which.equals(gsd.getRepository())) {
-				updateRevs(gsd);
-				shouldRefresh = true;
-			}
-		}
-
-		if (!shouldRefresh)
-			return;
-
-		subscriber.reset(this.gsds);
-		ResourceTraversal[] traversals = getScopeManager().getScope()
-				.getTraversals();
-		try {
-			subscriber.refresh(traversals, new NullProgressMonitor());
-		} catch (TeamException e) {
-			Activator.logError(
-					CoreText.GitSubscriberMergeContext_FailedRefreshSyncView, e);
-		}
-	}
-
-	private void handleResourceChange(IResourceDelta delta) {
-		IResourceDelta[] children = delta.getAffectedChildren();
-		for (IResourceDelta resourceDelta : children) {
-			IResource resource = resourceDelta.getResource();
-			RepositoryMapping mapping = RepositoryMapping.getMapping(resource);
-			if (mapping == null)
-				continue;
-
-			scanDeltaAndRefresh(mapping, resourceDelta);
-		}
-	}
-
-	private void scanDeltaAndRefresh(RepositoryMapping mapping,
-			IResourceDelta delta) {
-		Repository repo = mapping.getRepository();
-		GitResourceDeltaVisitor visitor = new GitResourceDeltaVisitor(repo);
-		try {
-			delta.accept(visitor);
-			Collection<IFile> files = visitor.getFileResourcesToUpdate();
-			if (files != null && files.isEmpty())
-				return;
-
-			for (GitSynchronizeData gsd : gsds) {
-				if (repo.equals(gsd.getRepository()))
-					refreshResources(files);
-			}
-		} catch (CoreException e) {
-			Activator.logError(e.getMessage(), e);
-		}
-	}
-
-	private void refreshResources(Collection<IFile> resources) {
-		IResource[] files = resources.toArray(new IResource[resources
-				.size()]);
-		try {
-			subscriber.refresh(files, IResource.DEPTH_ONE,
-					new NullProgressMonitor());
-		} catch (final CoreException e) {
-			Activator.logError(
-					CoreText.GitSubscriberMergeContext_FailedRefreshSyncView, e);
-		}
-	}
-
-	private void updateRevs(GitSynchronizeData gsd) {
-		try {
-			gsd.updateRevs();
-		} catch (IOException e) {
-			Activator.logError(
-					CoreText.GitSubscriberMergeContext_FailedUpdateRevs, e);
-			return;
-		}
-	}
-
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitSubscriberResourceMappingContext.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitSubscriberResourceMappingContext.java
deleted file mode 100644
index fc6ed8c..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitSubscriberResourceMappingContext.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.synchronize;
-
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
-import org.eclipse.team.core.subscribers.SubscriberResourceMappingContext;
-
-/**
- *
- */
-public class GitSubscriberResourceMappingContext extends
-		SubscriberResourceMappingContext {
-
-	private final GitSynchronizeDataSet data;
-
-	/**
-	 * @param subscriber
-	 * @param data
-	 */
-	public GitSubscriberResourceMappingContext(
-			GitResourceVariantTreeSubscriber subscriber,
-			GitSynchronizeDataSet data) {
-		super(subscriber, true);
-		this.data = data;
-	}
-
-	/**
-	 * @return git synchronize data set
-	 */
-	public GitSynchronizeDataSet getSyncData() {
-		return data;
-	}
-
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitSyncCache.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitSyncCache.java
deleted file mode 100644
index fdb6561..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitSyncCache.java
+++ /dev/null
@@ -1,219 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2011, Dariusz Luksza <dariusz@luksza.org> and others.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.synchronize;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.SubMonitor;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
-import org.eclipse.jgit.dircache.DirCache;
-import org.eclipse.jgit.dircache.DirCacheIterator;
-import org.eclipse.jgit.lib.AbbreviatedObjectId;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.jgit.treewalk.EmptyTreeIterator;
-import org.eclipse.jgit.treewalk.FileTreeIterator;
-import org.eclipse.jgit.treewalk.TreeWalk;
-import org.eclipse.jgit.treewalk.filter.AndTreeFilter;
-import org.eclipse.jgit.treewalk.filter.NotIgnoredFilter;
-import org.eclipse.jgit.treewalk.filter.OrTreeFilter;
-import org.eclipse.jgit.treewalk.filter.PathFilter;
-import org.eclipse.jgit.treewalk.filter.TreeFilter;
-
-/**
- * Simple and thin tree cache for git meta data about resources in repository.
- */
-class GitSyncCache {
-
-	private final Map<File, GitSyncObjectCache> cache;
-
-	public static GitSyncCache getAllData(GitSynchronizeDataSet gsds,
-			IProgressMonitor monitor) {
-		Map<GitSynchronizeData, Collection<String>> updateRequests = new HashMap<GitSynchronizeData, Collection<String>>();
-		for (GitSynchronizeData data : gsds)
-			updateRequests.put(data, Collections.<String> emptyList());
-		return getAllData(updateRequests, monitor);
-	}
-
-	public static GitSyncCache getAllData(
-			Map<GitSynchronizeData, Collection<String>> updateRequests,
-			IProgressMonitor monitor) {
-		GitSyncCache cache = new GitSyncCache();
-		SubMonitor m = SubMonitor.convert(monitor, updateRequests.size());
-
-		for (Entry<GitSynchronizeData, Collection<String>> entry : updateRequests
-				.entrySet()) {
-			cache.merge(getAllData(entry.getKey(), entry.getValue()));
-			m.worked(1);
-		}
-
-		m.done();
-		return cache;
-	}
-
-	private static GitSyncCache getAllData(GitSynchronizeData gsd,
-			Collection<String> paths) {
-		GitSyncCache cache = new GitSyncCache();
-		TreeFilter filter = paths.isEmpty() ? null : createPathFilter(paths);
-
-		Repository repo = gsd.getRepository();
-		ObjectId baseTree = getTree(gsd.getSrcRevCommit());
-		ObjectId remoteTree = getTree(gsd.getDstRevCommit());
-		GitSyncObjectCache repoCache = cache.put(repo, baseTree, remoteTree);
-
-		TreeFilter gsdFilter = gsd.getPathFilter();
-		if (filter == null)
-			loadDataFromGit(gsd, gsdFilter, repoCache);
-		else if (gsdFilter == null)
-			loadDataFromGit(gsd, filter, repoCache);
-		else
-			loadDataFromGit(gsd, AndTreeFilter.create(filter, gsdFilter),
-					repoCache);
-		return cache;
-	}
-
-	private static TreeFilter createPathFilter(Collection<String> paths) {
-		// do not use PathFilterGroup to create the filter, see bug 362430
-		List<TreeFilter> filters = new ArrayList<TreeFilter>(paths.size());
-		for (String path : paths) {
-			if (path.length() == 0)
-				return null;
-			filters.add(PathFilter.create(path));
-		}
-		if (filters.size() == 1)
-			return filters.get(0);
-		return OrTreeFilter.create(filters);
-	}
-
-	private static void loadDataFromGit(GitSynchronizeData gsd,
-			TreeFilter filter, GitSyncObjectCache repoCache) {
-		Repository repo = gsd.getRepository();
-		TreeWalk tw = new TreeWalk(repo);
-		if (filter != null)
-			tw.setFilter(filter);
-
-		try {
-			// setup local tree
-			FileTreeIterator fti = null;
-			if (gsd.shouldIncludeLocal()) {
-				fti = new FileTreeIterator(repo);
-				tw.addTree(fti);
-				if (filter != null)
-					tw.setFilter(AndTreeFilter.create(filter,
-							new NotIgnoredFilter(0)));
-				else
-					tw.setFilter(new NotIgnoredFilter(0));
-			} else if (gsd.getSrcRevCommit() != null)
-				tw.addTree(gsd.getSrcRevCommit().getTree());
-			else
-				tw.addTree(new EmptyTreeIterator());
-
-			// setup base tree
-			if (gsd.getCommonAncestorRev() != null)
-				tw.addTree(gsd.getCommonAncestorRev().getTree());
-			else
-				tw.addTree(new EmptyTreeIterator());
-
-			// setup remote tree
-			if (gsd.getDstRevCommit() != null)
-				tw.addTree(gsd.getDstRevCommit().getTree());
-			else
-				tw.addTree(new EmptyTreeIterator());
-
-			DirCacheIterator dci = null;
-			if (fti != null) {
-				dci = new DirCacheIterator(DirCache.read(repo));
-				tw.addTree(dci);
-				fti.setDirCacheIterator(tw, 3);
-			}
-			List<ThreeWayDiffEntry> diffEntrys = ThreeWayDiffEntry.scan(tw);
-			tw.release();
-
-			for (ThreeWayDiffEntry diffEntry : diffEntrys)
-				repoCache.addMember(diffEntry);
-		} catch (Exception e) {
-			Activator.logError(e.getMessage(), e);
-		}
-	}
-
-	private static ObjectId getTree(RevCommit commit) {
-		if (commit != null)
-			return commit.getTree();
-		else {
-			return ObjectId.zeroId();
-		}
-	}
-
-	private GitSyncCache() {
-		cache = new HashMap<File, GitSyncObjectCache>();
-	}
-
-	/**
-	 * @param repo
-	 *            instance of {@link Repository} for with mapping should be
-	 *            obtained
-	 * @return instance of {@link GitSyncObjectCache} connected associated with
-	 *         given repository or {@code null} when such mapping wasn't found
-	 */
-	public GitSyncObjectCache get(Repository repo) {
-		return cache.get(repo.getDirectory());
-	}
-
-	public void merge(GitSyncCache newCache) {
-		for (Entry<File, GitSyncObjectCache> entry : newCache.cache.entrySet()) {
-			File key = entry.getKey();
-			if (cache.containsKey(key))
-				cache.get(key).merge(entry.getValue());
-			else
-				cache.put(key, entry.getValue());
-		}
-	}
-
-	@Override
-	public String toString() {
-		StringBuilder builder = new StringBuilder();
-		for (Entry<File, GitSyncObjectCache> entry : cache.entrySet())
-			builder.append(entry.getKey().getPath())
-					.append(": ").append(entry.getValue()); //$NON-NLS-1$
-
-		return builder.toString();
-	}
-
-	/**
-	 * Create mapping for given repository and returns object associated with
-	 * this repository. Any other mapping will be overwritten.
-	 *
-	 * @param repo
-	 * @param remoteTree
-	 * @param baseTree
-	 * @return new mapping object associated with given {@link Repository}
-	 */
-	private GitSyncObjectCache put(Repository repo, ObjectId baseTree,
-			ObjectId remoteTree) {
-		ThreeWayDiffEntry entry = new ThreeWayDiffEntry();
-		entry.baseId = AbbreviatedObjectId.fromObjectId(baseTree);
-		entry.remoteId = AbbreviatedObjectId.fromObjectId(remoteTree);
-		GitSyncObjectCache objectCache = new GitSyncObjectCache("", entry); //$NON-NLS-1$
-		cache.put(repo.getDirectory(), objectCache);
-
-		return objectCache;
-	}
-
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitSyncInfo.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitSyncInfo.java
deleted file mode 100644
index bd65062..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitSyncInfo.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.synchronize;
-
-import static org.eclipse.jgit.lib.Repository.stripWorkDir;
-
-import org.eclipse.core.resources.IResource;
-import org.eclipse.egit.core.synchronize.ThreeWayDiffEntry.ChangeType;
-import org.eclipse.egit.core.synchronize.ThreeWayDiffEntry.Direction;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.team.core.TeamException;
-import org.eclipse.team.core.synchronize.SyncInfo;
-import org.eclipse.team.core.variants.IResourceVariant;
-import org.eclipse.team.core.variants.IResourceVariantComparator;
-
-class GitSyncInfo extends SyncInfo {
-
-	private final GitSyncObjectCache cache;
-	private final Repository repo;
-
-	public GitSyncInfo(IResource local, IResourceVariant base,
-			IResourceVariant remote, IResourceVariantComparator comparator,
-			GitSyncObjectCache cache, Repository repo) {
-		super(local, base, remote, comparator);
-		this.repo = repo;
-		this.cache = cache;
-	}
-
-	@Override
-	protected int calculateKind() throws TeamException {
-		if (cache.membersCount() == 0)
-			return IN_SYNC;
-
-		String path;
-		if (getLocal() != null && getLocal().getLocation() != null)
-			path = stripWorkDir(repo.getWorkTree(), getLocal().getLocation().toFile());
-		else if (getRemote() != null)
-			path = ((GitRemoteResource)getRemote()).getPath();
-		else if (getBase() != null)
-			path = ((GitRemoteResource)getBase()).getPath();
-		else
-			return IN_SYNC;
-
-		GitSyncObjectCache obj = cache.get(path);
-		if (obj == null)
-			return IN_SYNC;
-
-		int direction;
-		Direction gitDirection = obj.getDiffEntry().getDirection();
-		if (gitDirection == Direction.INCOMING)
-			direction = INCOMING;
-		else if (gitDirection == Direction.OUTGOING)
-			direction = OUTGOING;
-		else
-			direction = CONFLICTING;
-
-		ChangeType changeType = obj.getDiffEntry().getChangeType();
-
-		if (changeType == ChangeType.MODIFY)
-			return direction | CHANGE;
-		if (changeType == ChangeType.ADD)
-			return direction | ADDITION;
-		if (changeType == ChangeType.DELETE)
-			return direction | DELETION;
-
-		return IN_SYNC;
-	}
-
-	@Override
-	public boolean equals(Object other) {
-		return super.equals(other);
-	}
-
-	@Override
-	public int hashCode() {
-		return super.hashCode();
-	}
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitSyncObjectCache.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitSyncObjectCache.java
deleted file mode 100644
index 2f4cb97..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/GitSyncObjectCache.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2011, Dariusz Luksza <dariusz@luksza.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.synchronize;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import org.eclipse.egit.core.CoreText;
-import org.eclipse.egit.core.synchronize.ThreeWayDiffEntry.ChangeType;
-import org.eclipse.osgi.util.NLS;
-
-/**
- * Thin cache object. It contains list of object members, object name and
- * {@link ThreeWayDiffEntry} data.
- */
-class GitSyncObjectCache {
-
-	private final String name;
-
-	private final ThreeWayDiffEntry diffEntry;
-
-	private Map<String, GitSyncObjectCache> members;
-
-	/**
-	 * Creates node and leaf element
-	 *
-	 * @param name
-	 *            entry name
-	 * @param diffEntry
-	 *            entry meta data
-	 */
-	GitSyncObjectCache(String name, ThreeWayDiffEntry diffEntry) {
-		this.name = name;
-		this.diffEntry = diffEntry;
-	}
-
-	/**
-	 * @return name of this object
-	 */
-	public String getName() {
-		return name;
-	}
-
-	/**
-	 *
-	 * @return entry meta data
-	 */
-	public ThreeWayDiffEntry getDiffEntry() {
-		return diffEntry;
-	}
-
-	/**
-	 * Store given {@code entry} in cache. It assumes that parent of
-	 * {@code entry} is already in cache, if not {@link RuntimeException} will
-	 * be thrown.
-	 *
-	 * @param entry
-	 *            that should be stored in cache
-	 * @throws RuntimeException
-	 *             when cannot find parent of given {@code entry} in cache
-	 */
-	public void addMember(ThreeWayDiffEntry entry) {
-		String memberPath = entry.getPath();
-
-		if (members == null)
-			members = new HashMap<String, GitSyncObjectCache>();
-
-		int start = -1;
-		Map<String, GitSyncObjectCache> parent = members;
-		int separatorIdx = memberPath.indexOf("/"); //$NON-NLS-1$
-		while (separatorIdx > 0) {
-			String key = memberPath.substring(start + 1, separatorIdx);
-			GitSyncObjectCache cacheObject = parent.get(key);
-			if (cacheObject == null)
-				throw new RuntimeException(NLS.bind(
-						CoreText.GitSyncObjectCache_noData, key));
-
-			start = separatorIdx;
-			separatorIdx = memberPath.indexOf("/", separatorIdx + 1); //$NON-NLS-1$
-			if (cacheObject.members == null)
-				cacheObject.members = new HashMap<String, GitSyncObjectCache>();
-
-			parent = cacheObject.members;
-		}
-
-		String newName;
-		if (start > 0)
-			newName = memberPath.substring(start + 1);
-		else
-			newName = memberPath;
-
-		GitSyncObjectCache obj = new GitSyncObjectCache(newName, entry);
-		parent.put(newName, obj);
-	}
-
-	/**
-	 * @param childPath
-	 *            repository relative path of entry that should be obtained
-	 * @return cached object, or {@code null} when cache doen't contain object
-	 *         for given path
-	 */
-	public GitSyncObjectCache get(String childPath) {
-		if (childPath.length() == 0)
-			return this;
-		if (childPath
-				.substring(childPath.lastIndexOf("/") + 1, childPath.length()).equals(name)) //$NON-NLS-1$
-			return this;
-		if (members == null)
-			return null;
-
-		int start = -1;
-		Map<String, GitSyncObjectCache> parent = members;
-		int separatorIdx = childPath.indexOf("/"); //$NON-NLS-1$
-		while (separatorIdx > 0) {
-			String key = childPath.substring(start + 1, separatorIdx);
-
-			GitSyncObjectCache childObject = parent.get(key);
-			if (childObject == null)
-				return null;
-
-			start = separatorIdx;
-			separatorIdx = childPath.indexOf("/", separatorIdx + 1); //$NON-NLS-1$
-			parent = childObject.members;
-			if (parent == null)
-				return null;
-		}
-
-		return parent.get(childPath.subSequence(
-				childPath.lastIndexOf("/") + 1, childPath.length())); //$NON-NLS-1$
-	}
-
-	/**
-	 * @return number of cached members
-	 */
-	public int membersCount() {
-		return members != null ? members.size() : 0;
-	}
-
-	/**
-	 * @return list of all cached members or {@code null} when there this object
-	 *         doesn't contain members
-	 */
-	public Collection<GitSyncObjectCache> members() {
-		return members != null ? members.values() : null;
-	}
-
-	@Override
-	public String toString() {
-		StringBuilder builder = new StringBuilder();
-		builder.append("entry: ").append(diffEntry).append("\n"); //$NON-NLS-1$ //$NON-NLS-2$
-		if (members != null) {
-			builder.append("members: "); //$NON-NLS-1$
-			for (GitSyncObjectCache obj : members.values())
-				builder.append(obj.toString()).append("\n"); //$NON-NLS-1$
-		}
-
-		return builder.toString();
-	}
-
-	void merge(GitSyncObjectCache value) {
-		if (value.members != null) {
-			if (members == null)
-				members = new HashMap<String, GitSyncObjectCache>();
-			else
-				for (Entry<String, GitSyncObjectCache> entry : members
-						.entrySet())
-					if (!value.members.containsKey(entry.getKey()))
-						entry.getValue().diffEntry.changeType = ChangeType.IN_SYNC;
-
-			for (Entry<String, GitSyncObjectCache> entry : value.members
-					.entrySet()) {
-				String key = entry.getKey();
-				if (members.containsKey(key))
-					members.get(key).merge(entry.getValue());
-				else
-					members.put(key, entry.getValue());
-			}
-		} else if (members != null)
-			for (GitSyncObjectCache obj : members.values())
-				obj.diffEntry.changeType = ChangeType.IN_SYNC;
-		else // we should be on leaf entry, just update the change type value
-			diffEntry.changeType = value.diffEntry.changeType;
-	}
-
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/StagedChangeCache.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/StagedChangeCache.java
deleted file mode 100644
index 5aa5254..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/StagedChangeCache.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2011, Dariusz Luksza <dariusz@luksza.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.synchronize;
-
-import static org.eclipse.egit.core.synchronize.GitCommitsModelCache.RIGHT;
-import static org.eclipse.egit.core.synchronize.GitCommitsModelCache.calculateAndSetChangeKind;
-import static org.eclipse.jgit.lib.Constants.HEAD;
-import static org.eclipse.jgit.lib.FileMode.MISSING;
-import static org.eclipse.jgit.lib.FileMode.TREE;
-import static org.eclipse.jgit.lib.ObjectId.zeroId;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.synchronize.GitCommitsModelCache.Change;
-import org.eclipse.jgit.dircache.DirCacheIterator;
-import org.eclipse.jgit.lib.AbbreviatedObjectId;
-import org.eclipse.jgit.lib.MutableObjectId;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.jgit.revwalk.RevWalk;
-import org.eclipse.jgit.treewalk.EmptyTreeIterator;
-import org.eclipse.jgit.treewalk.TreeWalk;
-
-/**
- * Builds list of changes in git staging area.
- */
-public class StagedChangeCache {
-
-	/**
-	 * @param repo
-	 *            repository which should be scanned
-	 * @return list of changes in git staging area
-	 */
-	public static Map<String, Change> build(Repository repo) {
-		TreeWalk tw = new TreeWalk(repo);
-		try {
-			tw.addTree(new DirCacheIterator(repo.readDirCache()));
-			ObjectId headId = repo.resolve(HEAD);
-			RevCommit headCommit;
-			if (headId != null)
-				headCommit = new RevWalk(repo).parseCommit(headId);
-			else
-				headCommit = null;
-
-			AbbreviatedObjectId commitId;
-			if (headCommit != null) {
-				tw.addTree(headCommit.getTree());
-				commitId = AbbreviatedObjectId.fromObjectId(headCommit);
-			} else {
-				tw.addTree(new EmptyTreeIterator());
-				commitId =AbbreviatedObjectId.fromObjectId(zeroId());
-			}
-
-			tw.setRecursive(true);
-			headCommit = null;
-
-			MutableObjectId idBuf = new MutableObjectId();
-			Map<String, Change> result = new HashMap<String, Change>();
-			while(tw.next()) {
-				if (!shouldIncludeEntry(tw))
-					continue;
-
-				Change change = new Change();
-				change.name = tw.getNameString();
-				change.remoteCommitId = commitId;
-
-				tw.getObjectId(idBuf, 0);
-				change.objectId = AbbreviatedObjectId.fromObjectId(idBuf);
-				tw.getObjectId(idBuf, 1);
-				change.remoteObjectId = AbbreviatedObjectId.fromObjectId(idBuf);
-
-				calculateAndSetChangeKind(RIGHT, change);
-
-				result.put(tw.getPathString(), change);
-			}
-			tw.release();
-
-			return result;
-		} catch (IOException e) {
-			Activator.error(e.getMessage(), e);
-			return new HashMap<String, Change>(0);
-		}
-	}
-
-	private static boolean shouldIncludeEntry(TreeWalk tw) {
-		final int mHead = tw.getRawMode(1);
-		final int mCache = tw.getRawMode(0);
-
-		return mHead == MISSING.getBits() // initial add to cache
-				|| mCache == MISSING.getBits() // removed from cache
-				|| (mHead != mCache || (mCache != TREE.getBits() && !tw
-						.idEqual(1, 0))); // modified
-	}
-
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/ThreeWayDiffEntry.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/ThreeWayDiffEntry.java
deleted file mode 100644
index d3175e3..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/ThreeWayDiffEntry.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2011, Dariusz Luksza <dariusz@luksza.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.synchronize;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.eclipse.jgit.lib.AbbreviatedObjectId;
-import org.eclipse.jgit.lib.FileMode;
-import org.eclipse.jgit.lib.MutableObjectId;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.treewalk.TreeWalk;
-
-/**
- * Based on {@link org.eclipse.jgit.diff.DiffEntry}. Represents change to a file
- * with additional information about change direction.
- */
-public final class ThreeWayDiffEntry {
-
-	/** Magical SHA1 used for file adds or deletes */
-	private static final AbbreviatedObjectId A_ZERO = AbbreviatedObjectId
-			.fromObjectId(ObjectId.zeroId());
-
-	/** General type of change a single file-level patch describes. */
-	public static enum ChangeType {
-		/** Add a new file to the project */
-		ADD,
-
-		/** Modify an existing file in the project (content and/or mode) */
-		MODIFY,
-
-		/** Delete an existing file from the project */
-		DELETE,
-
-		/** Resource is in sync */
-		IN_SYNC;
-	}
-
-	/** Change direction */
-	public static enum Direction {
-		/**
-		 *
-		 */
-		INCOMING,
-
-		/**
-		 *
-		 */
-		OUTGOING,
-
-		/** */
-		CONFLICTING;
-	}
-
-	ThreeWayDiffEntry() {
-		// reduce the visibility of the default constructor
-	}
-
-	/**
-	 * Converts the TreeWalk into TreeWayDiffEntry headers.
-	 *
-	 * @param walk
-	 *            the TreeWalk to walk through. Must have exactly three trees in
-	 *            this order: local, base and remote and can't be recursive.
-	 * @return headers describing the changed file.
-	 * @throws IOException
-	 *             the repository cannot be accessed.
-	 * @throws IllegalArgumentException
-	 *             when {@code walk} doen't have exactly three trees, or when
-	 *             {@code walk} is recursive
-	 */
-	public static List<ThreeWayDiffEntry> scan(TreeWalk walk)
-			throws IOException {
-		if (walk.getTreeCount() != 3 && walk.getTreeCount() != 4)
-			throw new IllegalArgumentException(
-					"TreeWalk need to have three or four trees"); //$NON-NLS-1$
-		if (walk.isRecursive())
-			throw new IllegalArgumentException(
-					"TreeWalk shouldn't be recursive."); //$NON-NLS-1$
-
-		List<ThreeWayDiffEntry> r = new ArrayList<ThreeWayDiffEntry>();
-		MutableObjectId idBuf = new MutableObjectId();
-		while (walk.next()) {
-			ThreeWayDiffEntry e = new ThreeWayDiffEntry();
-
-			walk.getObjectId(idBuf, 0);
-			e.localId = AbbreviatedObjectId.fromObjectId(idBuf);
-
-			walk.getObjectId(idBuf, 1);
-			e.baseId = AbbreviatedObjectId.fromObjectId(idBuf);
-
-			walk.getObjectId(idBuf, 2);
-			e.remoteId = AbbreviatedObjectId.fromObjectId(idBuf);
-
-			boolean localSameAsBase = e.localId.equals(e.baseId);
-			if (!A_ZERO.equals(e.localId) && localSameAsBase
-					&& e.baseId.equals(e.remoteId))
-				continue;
-
-			e.path = walk.getPathString();
-			boolean localIsMissing = walk.getFileMode(0) == FileMode.MISSING;
-			boolean baseIsMissing = walk.getFileMode(1) == FileMode.MISSING;
-			boolean remoteIsMissing = walk.getFileMode(2) == FileMode.MISSING;
-
-			if (localIsMissing || baseIsMissing || remoteIsMissing) {
-				if (!localIsMissing && baseIsMissing && remoteIsMissing) {
-					e.direction = Direction.OUTGOING;
-					e.changeType = ChangeType.ADD;
-				} else if (localIsMissing && baseIsMissing && !remoteIsMissing) {
-					e.direction = Direction.INCOMING;
-					e.changeType = ChangeType.ADD;
-				} else if (!localIsMissing && !baseIsMissing && remoteIsMissing) {
-					e.direction = Direction.INCOMING;
-					e.changeType = ChangeType.DELETE;
-				} else if (localIsMissing && !baseIsMissing && !remoteIsMissing) {
-					e.direction = Direction.OUTGOING;
-					e.changeType = ChangeType.DELETE;
-				} else {
-					e.direction = Direction.CONFLICTING;
-					e.changeType = ChangeType.MODIFY;
-				}
-			} else {
-				if (localSameAsBase && !e.localId.equals(e.remoteId))
-					e.direction = Direction.INCOMING;
-				else if (e.remoteId.equals(e.baseId)
-						&& !e.remoteId.equals(e.localId))
-					e.direction = Direction.OUTGOING;
-				else
-					e.direction = Direction.CONFLICTING;
-
-				e.changeType = ChangeType.MODIFY;
-			}
-
-			r.add(e);
-			if (walk.isSubtree()) {
-				e.isTree = true;
-				walk.enterSubtree();
-			}
-		}
-
-		return r;
-	}
-
-	ChangeType changeType;
-
-	AbbreviatedObjectId baseId;
-
-	AbbreviatedObjectId remoteId;
-
-	private String path;
-
-	private Direction direction;
-
-	private AbbreviatedObjectId localId;
-
-	private boolean isTree = false;
-
-	/**
-	 * @return base id
-	 */
-	public AbbreviatedObjectId getBaseId() {
-		return baseId;
-	}
-
-	/**
-	 * @return path
-	 */
-	public String getPath() {
-		return path;
-	}
-
-	/**
-	 * @return {@code true} if entry represents tree, {@code false} otherwise
-	 */
-	public boolean isTree() {
-		return isTree;
-	}
-
-	/** @return the type of change this patch makes on {@link #getPath()} */
-	public ChangeType getChangeType() {
-		return changeType;
-	}
-
-	/**
-	 * Get the old object id from the <code>index</code>.
-	 *
-	 * @return the object id; null if there is no index line
-	 */
-	public AbbreviatedObjectId getLocalId() {
-		return localId;
-	}
-
-	/**
-	 * Get the new object id from the <code>index</code>.
-	 *
-	 * @return the object id; null if there is no index line
-	 */
-	public AbbreviatedObjectId getRemoteId() {
-		return remoteId;
-	}
-
-	/**
-	 * @return direction
-	 */
-	public Direction getDirection() {
-		return direction;
-	}
-
-	@Override
-	public String toString() {
-		StringBuilder buf = new StringBuilder();
-		buf.append("ThreeDiffEntry["); //$NON-NLS-1$
-		buf.append(changeType).append(" ").append(path); //$NON-NLS-1$
-		buf.append("]"); //$NON-NLS-1$
-
-		return buf.toString();
-	}
-
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/WorkingTreeChangeCache.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/WorkingTreeChangeCache.java
deleted file mode 100644
index 5bc3169..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/WorkingTreeChangeCache.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2011, Dariusz Luksza <dariusz@luksza.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.synchronize;
-
-import static org.eclipse.egit.core.synchronize.GitCommitsModelCache.RIGHT;
-import static org.eclipse.egit.core.synchronize.GitCommitsModelCache.calculateAndSetChangeKind;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.synchronize.GitCommitsModelCache.Change;
-import org.eclipse.jgit.dircache.DirCacheIterator;
-import org.eclipse.jgit.lib.AbbreviatedObjectId;
-import org.eclipse.jgit.lib.MutableObjectId;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.treewalk.FileTreeIterator;
-import org.eclipse.jgit.treewalk.TreeWalk;
-import org.eclipse.jgit.treewalk.filter.IndexDiffFilter;
-
-/**
- * Builds list of working tree changes.
- */
-public class WorkingTreeChangeCache {
-
-	/**
-	 * @param repo
-	 *            with should be scanned
-	 * @return list of changes in working tree
-	 */
-	public static Map<String, Change> build(Repository repo) {
-		TreeWalk tw = new TreeWalk(repo);
-		try {
-			int fileNth = tw.addTree(new FileTreeIterator(repo));
-			int cacheNth = tw.addTree(new DirCacheIterator(repo.readDirCache()));
-			tw.setFilter(new IndexDiffFilter(cacheNth, fileNth));
-			tw.setRecursive(true);
-
-			Map<String, Change> result = new HashMap<String, Change>();
-			MutableObjectId idBuf = new MutableObjectId();
-			while (tw.next()) {
-				Change change = new Change();
-				change.name = tw.getNameString();
-				tw.getObjectId(idBuf, 0);
-				change.objectId = AbbreviatedObjectId.fromObjectId(idBuf);
-				tw.getObjectId(idBuf, 1);
-				change.remoteObjectId = AbbreviatedObjectId.fromObjectId(idBuf);
-				calculateAndSetChangeKind(RIGHT, change);
-
-				result.put(tw.getPathString(), change);
-			}
-			tw.release();
-
-			return result;
-		} catch (IOException e) {
-			Activator.error(e.getMessage(), e);
-			return new HashMap<String, GitCommitsModelCache.Change>(0);
-		}
-	}
-
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/dto/GitSynchronizeData.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/dto/GitSynchronizeData.java
deleted file mode 100644
index 186f01a..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/dto/GitSynchronizeData.java
+++ /dev/null
@@ -1,334 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2010, 2011 Dariusz Luksza <dariusz@luksza.org> and others.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.synchronize.dto;
-
-import static org.eclipse.core.runtime.Assert.isNotNull;
-import static org.eclipse.egit.core.RevUtils.getCommonAncestor;
-import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_BRANCH_SECTION;
-import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_MERGE;
-import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_REMOTE;
-import static org.eclipse.jgit.lib.Constants.R_HEADS;
-import static org.eclipse.jgit.lib.Constants.R_REMOTES;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.regex.Pattern;
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IWorkspaceRoot;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.revwalk.ObjectWalk;
-import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
-import org.eclipse.jgit.treewalk.filter.TreeFilter;
-
-/**
- * Simple data transfer object containing all necessary information for
- * launching synchronization
- */
-public class GitSynchronizeData {
-
-	private static final IWorkspaceRoot ROOT = ResourcesPlugin.getWorkspace()
-					.getRoot();
-
-	/**
-	 * Matches all strings that start from R_HEADS
-	 */
-	public static final Pattern BRANCH_NAME_PATTERN = Pattern.compile("^" + R_HEADS + ".*?"); //$NON-NLS-1$ //$NON-NLS-2$
-
-	private final boolean includeLocal;
-
-	private final Repository repo;
-
-	private final String srcRemote;
-
-	private final String dstRemote;
-
-	private final String srcMerge;
-
-	private final String dstMerge;
-
-	private RevCommit srcRevCommit;
-
-	private RevCommit dstRevCommit;
-
-	private RevCommit ancestorRevCommit;
-
-	private final Set<IProject> projects;
-
-	private final String repoParentPath;
-
-	private final String srcRev;
-
-	private final String dstRev;
-
-	private TreeFilter pathFilter;
-
-	private Set<IContainer> includedPaths;
-
-	private static class RemoteConfig {
-		final String remote;
-		final String merge;
-		public RemoteConfig(String remote, String merge) {
-			this.remote = remote;
-			this.merge = merge;
-		}
-	}
-
-	/**
-	 * Constructs {@link GitSynchronizeData} object
-	 *
-	 * @param repository
-	 * @param srcRev
-	 * @param dstRev
-	 * @param includeLocal
-	 *            <code>true</code> if local changes should be included in
-	 *            comparison
-	 * @throws IOException
-	 */
-	public GitSynchronizeData(Repository repository, String srcRev,
-			String dstRev, boolean includeLocal) throws IOException {
-		isNotNull(repository);
-		isNotNull(srcRev);
-		isNotNull(dstRev);
-		repo = repository;
-		this.srcRev = srcRev;
-		this.dstRev = dstRev;
-		this.includeLocal = includeLocal;
-
-		RemoteConfig srcRemoteConfig = extractRemoteName(srcRev);
-		RemoteConfig dstRemoteConfig = extractRemoteName(dstRev);
-
-		srcRemote = srcRemoteConfig.remote;
-		srcMerge = srcRemoteConfig.merge;
-
-		dstRemote = dstRemoteConfig.remote;
-		dstMerge = dstRemoteConfig.merge;
-
-		repoParentPath = repo.getDirectory().getParentFile().getAbsolutePath();
-
-		projects = new HashSet<IProject>();
-		final IProject[] workspaceProjects = ROOT.getProjects();
-		for (IProject project : workspaceProjects) {
-			RepositoryMapping mapping = RepositoryMapping.getMapping(project);
-			if (mapping != null && mapping.getRepository() == repo)
-				projects.add(project);
-		}
-		updateRevs();
-	}
-
-	/**
-	 * Recalculates source, destination and ancestor Rev commits
-	 *
-	 * @throws IOException
-	 */
-	public void updateRevs() throws IOException {
-		ObjectWalk ow = new ObjectWalk(repo);
-		try {
-			srcRevCommit = getCommit(srcRev, ow);
-			dstRevCommit = getCommit(dstRev, ow);
-		} finally {
-			ow.release();
-		}
-
-		if (this.dstRevCommit != null && this.srcRevCommit != null)
-			this.ancestorRevCommit = getCommonAncestor(repo, this.srcRevCommit,
-					this.dstRevCommit);
-		else
-			this.ancestorRevCommit = null;
-	}
-
-	/**
-	 * @return instance of repository that should be synchronized
-	 */
-	public Repository getRepository() {
-		return repo;
-	}
-
-	/**
-	 * @return name of source remote or {@code null} when source branch is not a
-	 *         remote branch
-	 */
-	public String getSrcRemoteName() {
-		return srcRemote;
-	}
-
-	/**
-	 * @return ref specification of destination merge branch
-	 */
-	public String getDstMerge() {
-		return dstMerge;
-	}
-
-	/**
-	 * @return ref specification of source merge branch
-	 */
-	public String getSrcMerge() {
-		return srcMerge;
-	}
-
-	/**
-	 * @return name of destination remote or {@code null} when destination
-	 *         branch is not a remote branch
-	 */
-	public String getDstRemoteName() {
-		return dstRemote;
-	}
-
-	/**
-	 * @return synchronize source rev name
-	 */
-	public RevCommit getSrcRevCommit() {
-		return srcRevCommit;
-	}
-
-	/**
-	 * @return synchronize destination rev name
-	 */
-	public RevCommit getDstRevCommit() {
-		return dstRevCommit;
-	}
-
-	/**
-	 * @return list of project's that are connected with this repository
-	 */
-	public Set<IProject> getProjects() {
-		return Collections.unmodifiableSet(projects);
-	}
-
-	/**
-	 * @param file
-	 * @return <true> if given {@link File} is contained by this repository
-	 */
-	public boolean contains(File file) {
-		return file.getAbsoluteFile().toString().startsWith(repoParentPath);
-	}
-
-	/**
-	 * @return <code>true</code> if local changes should be included in
-	 *         comparison
-	 */
-	public boolean shouldIncludeLocal() {
-		return includeLocal;
-	}
-
-	/**
-	 * @return common ancestor commit
-	 */
-	public RevCommit getCommonAncestorRev() {
-		return ancestorRevCommit;
-	}
-
-	/**
-	 * @param includedPaths
-	 *            list of containers to be synchronized
-	 */
-	public void setIncludedPaths(Set<IContainer> includedPaths) {
-		this.includedPaths = includedPaths;
-		Set<String> paths = new HashSet<String>();
-		RepositoryMapping rm = RepositoryMapping.findRepositoryMapping(repo);
-		for (IContainer container : includedPaths) {
-			String repoRelativePath = rm.getRepoRelativePath(container);
-			if (repoRelativePath.length() > 0)
-				paths.add(repoRelativePath);
-		}
-
-		if (!paths.isEmpty())
-			pathFilter = PathFilterGroup.createFromStrings(paths);
-	}
-
-	/**
-	 * @return set of included paths or {@code null} when all paths should be
-	 *         included
-	 */
-	public Set<IContainer> getIncludedPaths() {
-		return includedPaths;
-	}
-
-	/**
-	 * Disposes all nested resources
-	 */
-	public void dispose() {
-		if (projects != null)
-			projects.clear();
-		if (includedPaths != null)
-			includedPaths.clear();
-	}
-
-	/**
-	 * @return instance of {@link TreeFilter} when synchronization was launched
-	 *         from nested node (like folder) or {@code null} otherwise
-	 */
-	public TreeFilter getPathFilter() {
-		return pathFilter;
-	}
-
-	/**
-	 * @return synchronization source rev
-	 */
-	public String getSrcRev() {
-		return srcRev;
-	}
-
-	/**
-	 * @return synchronization destination rev
-	 */
-	public String getDstRev() {
-		return dstRev;
-	}
-
-	private RemoteConfig extractRemoteName(String rev) {
-		if (rev.contains(R_REMOTES)) {
-			String remoteWithBranchName = rev.replaceAll(R_REMOTES, ""); //$NON-NLS-1$
-			int firstSeparator = remoteWithBranchName.indexOf("/"); //$NON-NLS-1$
-
-			String remote = remoteWithBranchName.substring(0, firstSeparator);
-			String name = remoteWithBranchName.substring(firstSeparator + 1,
-					remoteWithBranchName.length());
-
-			return new RemoteConfig(remote, R_HEADS + name);
-		} else {
-			String realName;
-			Ref ref;
-			try {
-				ref = repo.getRef(rev);
-			} catch (IOException e) {
-				ref = null;
-			}
-			if (ref != null && ref.isSymbolic())
-				realName = ref.getTarget().getName();
-			else
-				realName = rev;
-			String name = BRANCH_NAME_PATTERN.matcher(realName).replaceAll(""); //$NON-NLS-1$
-			String remote = repo.getConfig().getString(CONFIG_BRANCH_SECTION,
-					name, CONFIG_KEY_REMOTE);
-			String merge = repo.getConfig().getString(CONFIG_BRANCH_SECTION,
-					name, CONFIG_KEY_MERGE);
-
-			return new RemoteConfig(remote, merge);
-		}
-	}
-
-	private RevCommit getCommit(String rev, ObjectWalk ow) throws IOException {
-		if (rev.length() > 0) {
-			ObjectId id = repo.resolve(rev);
-			return id != null ? ow.parseCommit(id) : null;
-		} else
-			return null;
-	}
-
-}
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/dto/GitSynchronizeDataSet.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/dto/GitSynchronizeDataSet.java
deleted file mode 100644
index 8046f28..0000000
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/synchronize/dto/GitSynchronizeDataSet.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.core.synchronize.dto;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-import org.eclipse.core.resources.IProject;
-
-/**
- *
- */
-public class GitSynchronizeDataSet implements Iterable<GitSynchronizeData> {
-
-	private boolean containsFolderLevelSynchronizationRequest = false;
-
-	private final Set<GitSynchronizeData> gsdSet;
-
-	private final Map<String, GitSynchronizeData> projectMapping;
-
-	private final boolean forceFetch;
-
-	/**
-	 * Constructs GitSynchronizeDataSet.
-	 */
-	public GitSynchronizeDataSet() {
-		this(false);
-	}
-
-	/**
-	 * Constructs GitSynchronizeDataSet.
-	 *
-	 * @param forceFetch
-	 *            {@code true} for forcing fetch action before synchronization
-	 */
-	public GitSynchronizeDataSet(boolean forceFetch) {
-		this.forceFetch = forceFetch;
-		gsdSet = new HashSet<GitSynchronizeData>();
-		projectMapping = new HashMap<String, GitSynchronizeData>();
-	}
-
-	/**
-	 * Constructs GitSynchronizeDataSet and adds given element to set.
-	 *
-	 * @param data
-	 */
-	public GitSynchronizeDataSet(GitSynchronizeData data) {
-		this();
-		add(data);
-	}
-
-	/**
-	 * @param data
-	 */
-	public void add(GitSynchronizeData data) {
-		gsdSet.add(data);
-		if (data.getIncludedPaths() != null
-				&& data.getIncludedPaths().size() > 0)
-			containsFolderLevelSynchronizationRequest = true;
-
-		for (IProject proj : data.getProjects()) {
-			projectMapping.put(proj.getName(), data);
-		}
-	}
-
-	/**
-	 * @param project
-	 * @return <code>true</code> if project has corresponding data
-	 */
-	public boolean contains(IProject project) {
-		return projectMapping.containsKey(project.getName());
-	}
-
-	/**
-	 * @return {@code true} when at least one {@link GitSynchronizeData} is
-	 *         configured to include changes only for particular folder,
-	 *         {@code false} otherwise
-	 */
-	public boolean containsFolderLevelSynchronizationRequest() {
-		return containsFolderLevelSynchronizationRequest;
-	}
-
-	/**
-	 * @return number of {@link GitSynchronizeData} that are included in this
-	 *         set
-	 */
-	public int size() {
-		return gsdSet.size();
-	}
-
-	/**
-	 * @param projectName
-	 * @return <code>null</code> if project does not have corresponding data
-	 */
-	public GitSynchronizeData getData(String projectName) {
-		return projectMapping.get(projectName);
-	}
-
-	/**
-	 * @param project
-	 * @return <code>null</code> if project does not have corresponding data
-	 */
-	public GitSynchronizeData getData(IProject project) {
-		return projectMapping.get(project.getName());
-	}
-
-	public Iterator<GitSynchronizeData> iterator() {
-		return gsdSet.iterator();
-	}
-
-	/**
-	 * @return list of all resources
-	 */
-	public IProject[] getAllProjects() {
-		Set<IProject> resource = new HashSet<IProject>();
-		for (GitSynchronizeData data : gsdSet) {
-			resource.addAll(data.getProjects());
-		}
-		return resource.toArray(new IProject[resource.size()]);
-	}
-
-
-	/**
-	 * @return {@code true} when fetch action should be forced before
-	 *         synchronization, {@code false} otherwise.
-	 */
-	public boolean forceFetch() {
-		return forceFetch;
-	}
-
-
-	/**
-	 * Disposes all nested resources
-	 */
-	public void dispose() {
-		if (projectMapping != null)
-			projectMapping.clear();
-
-		if (gsdSet != null)
-			for (GitSynchronizeData gsd : gsdSet)
-				gsd.dispose();
-
-	}
-
-	@Override
-	public String toString() {
-		StringBuilder builder = new StringBuilder();
-
-		for (GitSynchronizeData data : gsdSet) {
-			builder.append(data.getRepository().getWorkTree());
-			builder.append(" "); //$NON-NLS-1$
-		}
-
-		return builder.toString();
-	}
-
-}
diff --git a/org.eclipse.egit.import/plugin.xml b/org.eclipse.egit.import/plugin.xml
index b6f9c7e..0643785 100644
--- a/org.eclipse.egit.import/plugin.xml
+++ b/org.eclipse.egit.import/plugin.xml
@@ -6,7 +6,7 @@
     <importer
            id="org.eclipse.egit.core.importer"
            name="%gitBundleImporter"
-           repository="org.eclipse.egit.core.GitProvider">
+           repository="org.eclipse.egit.core.internal.GitProvider">
         <supports
               prefix="scm:git:">
         </supports>
diff --git a/org.eclipse.egit.mylyn.ui/META-INF/MANIFEST.MF b/org.eclipse.egit.mylyn.ui/META-INF/MANIFEST.MF
index ed93e78..f370360 100644
--- a/org.eclipse.egit.mylyn.ui/META-INF/MANIFEST.MF
+++ b/org.eclipse.egit.mylyn.ui/META-INF/MANIFEST.MF
@@ -25,8 +25,8 @@
 Bundle-Localization: plugin
 Export-Package: org.eclipse.egit.internal.mylyn.ui;version="3.0.0";x-friends:="org.eclipse.egit.ui.test",
  org.eclipse.egit.internal.mylyn.ui.commit;version="3.0.0";x-internal:=true
-Import-Package: org.eclipse.egit.core;version="[3.0.0,3.1.0)",
- org.eclipse.egit.core.synchronize;version="[3.0.0,3.1.0)",
+Import-Package: org.eclipse.egit.core.internal;version="3.0.0",
+ org.eclipse.egit.core.internal.synchronize;version="[3.0.0,3.1.0)",
  org.eclipse.egit.ui;version="[3.0.0,3.1.0)",
  org.eclipse.egit.ui.internal.commit;version="[3.0.0,3.1.0)",
  org.eclipse.egit.ui.internal.synchronize.model;version="[3.0.0,3.1.0)",
diff --git a/org.eclipse.egit.mylyn.ui/src/org/eclipse/egit/internal/mylyn/ui/CommitHyperlinkDetector.java b/org.eclipse.egit.mylyn.ui/src/org/eclipse/egit/internal/mylyn/ui/CommitHyperlinkDetector.java
index 34fec85..835ebe7 100644
--- a/org.eclipse.egit.mylyn.ui/src/org/eclipse/egit/internal/mylyn/ui/CommitHyperlinkDetector.java
+++ b/org.eclipse.egit.mylyn.ui/src/org/eclipse/egit/internal/mylyn/ui/CommitHyperlinkDetector.java
@@ -19,9 +19,9 @@
 import java.util.regex.Pattern;
 
 import org.eclipse.core.runtime.Assert;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.RepositoryCache;
-import org.eclipse.egit.core.RepositoryUtil;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.RepositoryCache;
+import org.eclipse.egit.core.internal.RepositoryUtil;
 import org.eclipse.egit.ui.internal.commit.CommitEditor;
 import org.eclipse.egit.ui.internal.commit.RepositoryCommit;
 import org.eclipse.jface.dialogs.MessageDialog;
diff --git a/org.eclipse.egit.mylyn.ui/src/org/eclipse/egit/internal/mylyn/ui/commit/TaskReferenceFactory.java b/org.eclipse.egit.mylyn.ui/src/org/eclipse/egit/internal/mylyn/ui/commit/TaskReferenceFactory.java
index f201fda..a5f6bbc 100644
--- a/org.eclipse.egit.mylyn.ui/src/org/eclipse/egit/internal/mylyn/ui/commit/TaskReferenceFactory.java
+++ b/org.eclipse.egit.mylyn.ui/src/org/eclipse/egit/internal/mylyn/ui/commit/TaskReferenceFactory.java
@@ -21,7 +21,7 @@
 import org.eclipse.core.runtime.IAdapterFactory;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
-import org.eclipse.egit.core.Activator;
+import org.eclipse.egit.core.internal.Activator;
 import org.eclipse.egit.internal.mylyn.ui.EGitMylynUI;
 import org.eclipse.egit.ui.internal.synchronize.model.GitModelCommit;
 import org.eclipse.egit.ui.internal.synchronize.model.GitModelRepository;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/common/CommitDialogTester.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/common/CommitDialogTester.java
index 6e15682..bd7f0e2 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/common/CommitDialogTester.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/common/CommitDialogTester.java
@@ -9,7 +9,7 @@
 package org.eclipse.egit.ui.common;
 
 import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.test.ContextMenuHelper;
 import org.eclipse.egit.ui.test.TestUtil;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/common/LocalRepositoryTestCase.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/common/LocalRepositoryTestCase.java
index 3327b8c..2dceb5a 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/common/LocalRepositoryTestCase.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/common/LocalRepositoryTestCase.java
@@ -30,15 +30,15 @@
 import org.eclipse.core.runtime.Path;
 import org.eclipse.core.runtime.preferences.IEclipsePreferences;
 import org.eclipse.core.runtime.preferences.InstanceScope;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.GitCorePreferences;
-import org.eclipse.egit.core.RepositoryCache;
-import org.eclipse.egit.core.op.AddToIndexOperation;
-import org.eclipse.egit.core.op.CloneOperation;
-import org.eclipse.egit.core.op.CommitOperation;
-import org.eclipse.egit.core.op.ConnectProviderOperation;
-import org.eclipse.egit.core.op.ListRemoteOperation;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.GitCorePreferences;
+import org.eclipse.egit.core.internal.RepositoryCache;
+import org.eclipse.egit.core.internal.op.AddToIndexOperation;
+import org.eclipse.egit.core.internal.op.CloneOperation;
+import org.eclipse.egit.core.internal.op.CommitOperation;
+import org.eclipse.egit.core.internal.op.ConnectProviderOperation;
+import org.eclipse.egit.core.internal.op.ListRemoteOperation;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.push.PushOperationUI;
 import org.eclipse.egit.ui.test.ContextMenuHelper;
 import org.eclipse.egit.ui.test.Eclipse;
@@ -145,18 +145,18 @@
 			FileUtils.mkdir(repoRoot, true);
 		// suppress auto-ignoring and auto-sharing to avoid interference
 		IEclipsePreferences corePrefs = InstanceScope.INSTANCE
-				.getNode(org.eclipse.egit.core.Activator.getPluginId());
+				.getNode(org.eclipse.egit.core.internal.Activator.getPluginId());
 		corePrefs.putBoolean(
 				GitCorePreferences.core_autoIgnoreDerivedResources, false);
 		corePrefs.putBoolean(GitCorePreferences.core_autoShareProjects, false);
 		// make sure the default directory for Repos is not the user home
-		org.eclipse.egit.ui.Activator.getDefault().getPreferenceStore()
+		org.eclipse.egit.ui.internal.Activator.getDefault().getPreferenceStore()
 				.setValue(UIPreferences.DEFAULT_REPO_DIR, repoRoot.getPath());
 		// suppress the configuration dialog
-		org.eclipse.egit.ui.Activator.getDefault().getPreferenceStore()
+		org.eclipse.egit.ui.internal.Activator.getDefault().getPreferenceStore()
 				.setValue(UIPreferences.SHOW_INITIAL_CONFIG_DIALOG, false);
 		// suppress the detached head warning dialog
-		org.eclipse.egit.ui.Activator
+		org.eclipse.egit.ui.internal.Activator
 				.getDefault()
 				.getPreferenceStore()
 				.setValue(UIPreferences.SHOW_DETACHED_HEAD_WARNING,
@@ -414,7 +414,7 @@
 
 	protected static FileRepository lookupRepository(File directory)
 			throws Exception {
-		return (FileRepository) org.eclipse.egit.core.Activator.getDefault()
+		return (FileRepository) org.eclipse.egit.core.internal.Activator.getDefault()
 				.getRepositoryCache().lookupRepository(directory);
 	}
 
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/common/StagingViewTester.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/common/StagingViewTester.java
index 603af72..d476744 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/common/StagingViewTester.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/common/StagingViewTester.java
@@ -9,7 +9,7 @@
 package org.eclipse.egit.ui.common;
 
 import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.staging.StagingView;
 import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/common/WorkingCopyPage.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/common/WorkingCopyPage.java
index f8ed7c9..12fd4fd 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/common/WorkingCopyPage.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/common/WorkingCopyPage.java
@@ -15,7 +15,7 @@
 
 import java.io.File;
 
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot;
 import org.eclipse.swtbot.swt.finder.waits.Conditions;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/httpauth/PushTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/httpauth/PushTest.java
index 519f618..1733245 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/httpauth/PushTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/httpauth/PushTest.java
@@ -14,8 +14,8 @@
 import java.io.File;
 
 import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.op.CloneOperation;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.op.CloneOperation;
 import org.eclipse.egit.ui.common.EGitTestCase;
 import org.eclipse.egit.ui.common.LoginDialogTester;
 import org.eclipse.egit.ui.common.PushResultDialogTester;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/branch/BranchProjectTrackerTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/branch/BranchProjectTrackerTest.java
index 6e7c975..e94b9ea 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/branch/BranchProjectTrackerTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/branch/BranchProjectTrackerTest.java
@@ -20,9 +20,9 @@
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.core.internal.Activator;
 import org.eclipse.egit.ui.common.LocalRepositoryTestCase;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.test.TestUtil;
 import org.eclipse.jgit.api.Git;
 import org.eclipse.jgit.lib.Constants;
@@ -48,9 +48,9 @@
 				.lookupRepository(repoFile);
 		assertNotNull(repository);
 		BranchProjectTracker tracker = new BranchProjectTracker(repository);
-		org.eclipse.egit.ui.Activator.getDefault().getPreferenceStore()
+		org.eclipse.egit.ui.internal.Activator.getDefault().getPreferenceStore()
 				.setValue(tracker.getPreference(Constants.MASTER), "");
-		org.eclipse.egit.ui.Activator.getDefault().getPreferenceStore()
+		org.eclipse.egit.ui.internal.Activator.getDefault().getPreferenceStore()
 				.setValue(tracker.getPreference(BRANCH), "");
 	}
 
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/decorators/DecoratableResourceAdapterTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/decorators/DecoratableResourceAdapterTest.java
index f94e9e2..e637b73 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/decorators/DecoratableResourceAdapterTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/decorators/DecoratableResourceAdapterTest.java
@@ -23,8 +23,8 @@
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.JobFamilies;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.JobFamilies;
 import org.eclipse.egit.core.internal.indexdiff.IndexDiffCacheEntry;
 import org.eclipse.egit.core.internal.indexdiff.IndexDiffData;
 import org.eclipse.egit.ui.common.LocalRepositoryTestCase;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitChangeSetSorterTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitChangeSetSorterTest.java
index e589d4c..1464ecb 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitChangeSetSorterTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitChangeSetSorterTest.java
@@ -14,7 +14,7 @@
 
 import java.util.Date;
 
-import org.eclipse.egit.core.synchronize.GitCommitsModelCache.Commit;
+import org.eclipse.egit.core.internal.synchronize.GitCommitsModelCache.Commit;
 import org.eclipse.egit.ui.internal.synchronize.model.GitModelBlob;
 import org.eclipse.egit.ui.internal.synchronize.model.GitModelCache;
 import org.eclipse.egit.ui.internal.synchronize.model.GitModelCommit;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelBlobTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelBlobTest.java
index 15da12b..3db90df 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelBlobTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelBlobTest.java
@@ -23,8 +23,8 @@
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.core.synchronize.GitCommitsModelCache.Change;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.synchronize.GitCommitsModelCache.Change;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.jgit.lib.AbbreviatedObjectId;
 import org.eclipse.jgit.lib.ObjectId;
 import org.junit.BeforeClass;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelCacheFileTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelCacheFileTest.java
index 7d83213..03a370e 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelCacheFileTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelCacheFileTest.java
@@ -16,8 +16,8 @@
 import static org.mockito.Mockito.when;
 
 import org.eclipse.core.runtime.IPath;
-import org.eclipse.egit.core.synchronize.GitCommitsModelCache.Change;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.synchronize.GitCommitsModelCache.Change;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.jgit.lib.AbbreviatedObjectId;
 import org.eclipse.jgit.lib.ObjectId;
 import org.junit.BeforeClass;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelCacheTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelCacheTest.java
index 0f7ef5c..2b12c68 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelCacheTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelCacheTest.java
@@ -17,9 +17,9 @@
 import java.io.File;
 import java.util.Map;
 
-import org.eclipse.egit.core.synchronize.GitCommitsModelCache.Change;
-import org.eclipse.egit.core.synchronize.StagedChangeCache;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.synchronize.StagedChangeCache;
+import org.eclipse.egit.core.internal.synchronize.GitCommitsModelCache.Change;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.jgit.api.Git;
 import org.eclipse.jgit.internal.storage.file.FileRepository;
 import org.junit.BeforeClass;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelCacheTreeTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelCacheTreeTest.java
index 20f2198..cc5e125 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelCacheTreeTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelCacheTreeTest.java
@@ -13,8 +13,8 @@
 import static org.mockito.Mockito.mock;
 
 import org.eclipse.core.runtime.IPath;
-import org.eclipse.egit.core.synchronize.GitCommitsModelCache.Change;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.synchronize.GitCommitsModelCache.Change;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.synchronize.model.TreeBuilder.FileModelFactory;
 import org.eclipse.jgit.lib.Repository;
 import org.junit.BeforeClass;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelCommitTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelCommitTest.java
index 4311422..d81b2bb 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelCommitTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelCommitTest.java
@@ -15,7 +15,7 @@
 
 import java.io.File;
 
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelRepositoryTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelRepositoryTest.java
index 39a330e..7ecbba8 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelRepositoryTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelRepositoryTest.java
@@ -11,7 +11,7 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.jgit.lib.Repository;
 import org.junit.BeforeClass;
 import org.junit.Test;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelRootTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelRootTest.java
index bf45080..0072d81 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelRootTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelRootTest.java
@@ -14,8 +14,8 @@
 
 import java.io.File;
 
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeData;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeDataSet;
 import org.eclipse.jgit.lib.Repository;
 import org.junit.BeforeClass;
 import org.junit.Test;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelTestCase.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelTestCase.java
index 4b04616..ec8d5fa 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelTestCase.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelTestCase.java
@@ -17,8 +17,8 @@
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.core.synchronize.GitCommitsModelCache.Commit;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
+import org.eclipse.egit.core.internal.synchronize.GitCommitsModelCache.Commit;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeData;
 import org.eclipse.egit.ui.common.LocalRepositoryTestCase;
 import org.eclipse.jgit.lib.AbbreviatedObjectId;
 import org.eclipse.jgit.lib.Constants;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelTreeTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelTreeTest.java
index e3f9f86..bee13ba 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelTreeTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelTreeTest.java
@@ -15,7 +15,7 @@
 import static org.mockito.Mockito.mock;
 
 import org.eclipse.core.runtime.IPath;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelWorkingFileTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelWorkingFileTest.java
index 3ae13b5..12e74f6 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelWorkingFileTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelWorkingFileTest.java
@@ -13,7 +13,7 @@
 import static org.mockito.Mockito.mock;
 
 import org.eclipse.core.runtime.IPath;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelWorkingTreeTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelWorkingTreeTest.java
index d45f163..fe3af6e 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelWorkingTreeTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelWorkingTreeTest.java
@@ -12,7 +12,7 @@
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
 
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/search/CommitSearchDialogTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/search/CommitSearchDialogTest.java
index 5fdc410..61ab5be 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/search/CommitSearchDialogTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/search/CommitSearchDialogTest.java
@@ -16,7 +16,7 @@
 
 import java.io.File;
 
-import org.eclipse.egit.core.Activator;
+import org.eclipse.egit.core.internal.Activator;
 import org.eclipse.egit.ui.common.LocalRepositoryTestCase;
 import org.eclipse.egit.ui.internal.commit.RepositoryCommit;
 import org.eclipse.egit.ui.internal.search.CommitSearchPage;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/search/CommitSearchQueryTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/search/CommitSearchQueryTest.java
index 5da4e9d..ffdb27c 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/search/CommitSearchQueryTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/search/CommitSearchQueryTest.java
@@ -19,7 +19,7 @@
 
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.egit.core.Activator;
+import org.eclipse.egit.core.internal.Activator;
 import org.eclipse.egit.ui.common.LocalRepositoryTestCase;
 import org.eclipse.egit.ui.internal.commit.RepositoryCommit;
 import org.eclipse.egit.ui.internal.search.CommitSearchQuery;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/submodule/SubmoduleAddTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/submodule/SubmoduleAddTest.java
index 870ae5e..dd5647a 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/submodule/SubmoduleAddTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/submodule/SubmoduleAddTest.java
@@ -15,8 +15,8 @@
 
 import java.io.File;
 
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.test.ContextMenuHelper;
 import org.eclipse.egit.ui.test.TestUtil;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/submodule/SubmoduleSyncTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/submodule/SubmoduleSyncTest.java
index 2a73d40..88fa749 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/submodule/SubmoduleSyncTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/submodule/SubmoduleSyncTest.java
@@ -15,8 +15,8 @@
 
 import java.io.File;
 
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.test.ContextMenuHelper;
 import org.eclipse.egit.ui.test.TestUtil;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/submodule/SubmoduleUpdateTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/submodule/SubmoduleUpdateTest.java
index 8a118b1..0f27132 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/submodule/SubmoduleUpdateTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/submodule/SubmoduleUpdateTest.java
@@ -17,8 +17,8 @@
 
 import java.io.File;
 
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.test.ContextMenuHelper;
 import org.eclipse.egit.ui.test.TestUtil;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/TestUtil.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/TestUtil.java
index a277334..0b182de 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/TestUtil.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/TestUtil.java
@@ -31,7 +31,7 @@
 
 import org.eclipse.core.net.proxy.IProxyService;
 import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.commit.CommitHelper;
 import org.eclipse.egit.ui.internal.commit.CommitHelper.CommitInfo;
 import org.eclipse.jgit.lib.ConfigConstants;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/commit/CommitEditorInputFactoryTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/commit/CommitEditorInputFactoryTest.java
index 9419d39..ed557f6 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/commit/CommitEditorInputFactoryTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/commit/CommitEditorInputFactoryTest.java
@@ -17,7 +17,7 @@
 import java.io.File;
 
 import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.egit.core.Activator;
+import org.eclipse.egit.core.internal.Activator;
 import org.eclipse.egit.ui.common.LocalRepositoryTestCase;
 import org.eclipse.egit.ui.internal.commit.CommitEditorInput;
 import org.eclipse.egit.ui.internal.commit.CommitEditorInputFactory;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/commit/CommitEditorInputTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/commit/CommitEditorInputTest.java
index 199773b..3c2419b 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/commit/CommitEditorInputTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/commit/CommitEditorInputTest.java
@@ -17,7 +17,7 @@
 import java.io.File;
 
 import org.eclipse.core.runtime.AssertionFailedException;
-import org.eclipse.egit.core.Activator;
+import org.eclipse.egit.core.internal.Activator;
 import org.eclipse.egit.ui.common.LocalRepositoryTestCase;
 import org.eclipse.egit.ui.internal.commit.CommitEditorInput;
 import org.eclipse.egit.ui.internal.commit.RepositoryCommit;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/commit/CommitEditorTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/commit/CommitEditorTest.java
index 40a0fe5..c44954e 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/commit/CommitEditorTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/commit/CommitEditorTest.java
@@ -18,9 +18,9 @@
 import java.io.File;
 import java.util.concurrent.atomic.AtomicReference;
 
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.core.internal.Activator;
 import org.eclipse.egit.ui.common.LocalRepositoryTestCase;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.commit.CommitEditor;
 import org.eclipse.egit.ui.internal.commit.RepositoryCommit;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/commit/DiffStyleRangeFormatterTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/commit/DiffStyleRangeFormatterTest.java
index 64cc3ba..ffaa7f5 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/commit/DiffStyleRangeFormatterTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/commit/DiffStyleRangeFormatterTest.java
@@ -15,7 +15,7 @@
 
 import java.io.File;
 
-import org.eclipse.egit.core.Activator;
+import org.eclipse.egit.core.internal.Activator;
 import org.eclipse.egit.ui.common.LocalRepositoryTestCase;
 import org.eclipse.egit.ui.internal.commit.DiffStyleRangeFormatter;
 import org.eclipse.egit.ui.internal.commit.DiffStyleRangeFormatter.DiffStyleRange;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/commit/RepositoryCommitTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/commit/RepositoryCommitTest.java
index c122f05..6a75725 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/commit/RepositoryCommitTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/commit/RepositoryCommitTest.java
@@ -18,7 +18,7 @@
 import java.io.File;
 
 import org.eclipse.core.runtime.AssertionFailedException;
-import org.eclipse.egit.core.Activator;
+import org.eclipse.egit.core.internal.Activator;
 import org.eclipse.egit.ui.common.LocalRepositoryTestCase;
 import org.eclipse.egit.ui.internal.commit.RepositoryCommit;
 import org.eclipse.egit.ui.internal.history.FileDiff;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/history/HistoryViewTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/history/HistoryViewTest.java
index f60ffac..04d7d1c 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/history/HistoryViewTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/history/HistoryViewTest.java
@@ -23,8 +23,8 @@
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.egit.ui.JobFamilies;
 import org.eclipse.egit.ui.common.LocalRepositoryTestCase;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.test.ContextMenuHelper;
 import org.eclipse.egit.ui.test.TestUtil;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/stagview/StagingViewTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/stagview/StagingViewTest.java
index 7f4f47d..db8cb9b 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/stagview/StagingViewTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/stagview/StagingViewTest.java
@@ -14,10 +14,10 @@
 
 import java.io.File;
 
-import org.eclipse.egit.core.JobFamilies;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.JobFamilies;
 import org.eclipse.egit.ui.common.LocalRepositoryTestCase;
 import org.eclipse.egit.ui.common.StagingViewTester;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.test.CommitMessageUtil;
 import org.eclipse.egit.ui.test.TestUtil;
 import org.eclipse.egit.ui.view.repositories.GitRepositoriesViewTestUtils;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/BranchAndResetActionTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/BranchAndResetActionTest.java
index e9a3a4f..09ddf78 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/BranchAndResetActionTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/BranchAndResetActionTest.java
@@ -32,12 +32,12 @@
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.Path;
 import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.egit.core.op.BranchOperation;
-import org.eclipse.egit.core.op.CommitOperation;
-import org.eclipse.egit.core.op.TagOperation;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.core.internal.op.BranchOperation;
+import org.eclipse.egit.core.internal.op.CommitOperation;
+import org.eclipse.egit.core.internal.op.TagOperation;
 import org.eclipse.egit.ui.common.LocalRepositoryTestCase;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.repository.RepositoriesViewLabelProvider;
 import org.eclipse.egit.ui.internal.repository.tree.LocalNode;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/CommitActionTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/CommitActionTest.java
index ff5dd45..02d960e 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/CommitActionTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/CommitActionTest.java
@@ -22,14 +22,14 @@
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.egit.core.op.BranchOperation;
-import org.eclipse.egit.core.op.TagOperation;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.core.internal.op.BranchOperation;
+import org.eclipse.egit.core.internal.op.TagOperation;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
 import org.eclipse.egit.ui.common.CommitDialogTester;
 import org.eclipse.egit.ui.common.CommitDialogTester.NoFilesToCommitPopup;
 import org.eclipse.egit.ui.common.LocalRepositoryTestCase;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.test.CommitMessageUtil;
 import org.eclipse.egit.ui.test.TestUtil;
 import org.eclipse.jgit.lib.ConfigConstants;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/CommitNonWSChangesTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/CommitNonWSChangesTest.java
index 7a61777..bae17d6 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/CommitNonWSChangesTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/CommitNonWSChangesTest.java
@@ -16,9 +16,9 @@
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.JobFamilies;
 import org.eclipse.egit.ui.common.LocalRepositoryTestCase;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.test.TestUtil;
 import org.eclipse.egit.ui.view.repositories.GitRepositoriesViewTestUtils;
@@ -49,7 +49,7 @@
 		repositoryFile = createProjectAndCommitToRepository();
 		Activator.getDefault().getRepositoryUtil()
 				.addConfiguredRepository(repositoryFile);
-		repository = org.eclipse.egit.core.Activator.getDefault()
+		repository = org.eclipse.egit.core.internal.Activator.getDefault()
 				.getRepositoryCache().lookupRepository(repositoryFile);
 	}
 
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/CompareActionsTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/CompareActionsTest.java
index 26d7e34..92f82e8 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/CompareActionsTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/CompareActionsTest.java
@@ -19,9 +19,9 @@
 
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.egit.core.op.BranchOperation;
-import org.eclipse.egit.core.op.ResetOperation;
-import org.eclipse.egit.core.op.TagOperation;
+import org.eclipse.egit.core.internal.op.BranchOperation;
+import org.eclipse.egit.core.internal.op.ResetOperation;
+import org.eclipse.egit.core.internal.op.TagOperation;
 import org.eclipse.egit.ui.common.LocalRepositoryTestCase;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.dialogs.CompareTreeView;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/CreatePatchActionTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/CreatePatchActionTest.java
index d5de0e6..eca478e 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/CreatePatchActionTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/CreatePatchActionTest.java
@@ -20,10 +20,10 @@
 import org.eclipse.core.resources.IFolder;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.egit.core.CoreText;
-import org.eclipse.egit.core.op.CommitOperation;
-import org.eclipse.egit.core.op.ResetOperation;
-import org.eclipse.egit.core.op.TagOperation;
+import org.eclipse.egit.core.internal.CoreText;
+import org.eclipse.egit.core.internal.op.CommitOperation;
+import org.eclipse.egit.core.internal.op.ResetOperation;
+import org.eclipse.egit.core.internal.op.TagOperation;
 import org.eclipse.egit.ui.common.CreatePatchWizard;
 import org.eclipse.egit.ui.common.CreatePatchWizard.NoChangesPopup;
 import org.eclipse.egit.ui.common.LocalRepositoryTestCase;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/DisconnectConnectTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/DisconnectConnectTest.java
index 73ff8a1..b2c405a 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/DisconnectConnectTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/DisconnectConnectTest.java
@@ -16,7 +16,7 @@
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.egit.core.project.RepositoryMapping;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
 import org.eclipse.egit.ui.common.LocalRepositoryTestCase;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.test.ContextMenuHelper;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/FetchAndMergeActionTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/FetchAndMergeActionTest.java
index 625a6b8..6637239 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/FetchAndMergeActionTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/FetchAndMergeActionTest.java
@@ -17,8 +17,8 @@
 import java.io.File;
 import java.util.concurrent.TimeUnit;
 
-import org.eclipse.egit.ui.JobFamilies;
 import org.eclipse.egit.ui.common.LocalRepositoryTestCase;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.repository.RepositoriesViewLabelProvider;
 import org.eclipse.egit.ui.internal.repository.tree.LocalNode;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/MergeToolTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/MergeToolTest.java
index 81db116..35e2a81 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/MergeToolTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/MergeToolTest.java
@@ -16,8 +16,8 @@
 
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.core.JobFamilies;
-import org.eclipse.egit.core.op.MergeOperation;
+import org.eclipse.egit.core.internal.JobFamilies;
+import org.eclipse.egit.core.internal.op.MergeOperation;
 import org.eclipse.egit.ui.common.LocalRepositoryTestCase;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.test.ContextMenuHelper;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/ReplaceActionsTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/ReplaceActionsTest.java
index 20c1fa3..9daf6aa 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/ReplaceActionsTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/ReplaceActionsTest.java
@@ -21,10 +21,10 @@
 
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.egit.core.op.BranchOperation;
-import org.eclipse.egit.core.op.TagOperation;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.core.internal.op.BranchOperation;
+import org.eclipse.egit.core.internal.op.TagOperation;
 import org.eclipse.egit.ui.common.LocalRepositoryTestCase;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.test.ContextMenuHelper;
 import org.eclipse.egit.ui.test.TestUtil;
@@ -146,7 +146,7 @@
 		selectDialog = bot.shell(UIText.CommitSelectDialog_WindowTitle);
 		selectDialog.bot().table().select(1);
 		selectDialog.bot().button(IDialogConstants.OK_LABEL).click();
-		TestUtil.joinJobs(org.eclipse.egit.ui.JobFamilies.DISCARD_CHANGES);
+		TestUtil.joinJobs(org.eclipse.egit.ui.internal.JobFamilies.DISCARD_CHANGES);
 		oldContent = getTestFileContent();
 		assertFalse(newContent.equals(oldContent));
 		// cleanup: checkout again master and delete merged branch
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/TagActionTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/TagActionTest.java
index e60fe18..067467c 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/TagActionTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/team/actions/TagActionTest.java
@@ -17,8 +17,8 @@
 
 import java.io.File;
 
-import org.eclipse.egit.core.op.BranchOperation;
-import org.eclipse.egit.core.op.TagOperation;
+import org.eclipse.egit.core.internal.op.BranchOperation;
+import org.eclipse.egit.core.internal.op.TagOperation;
 import org.eclipse.egit.ui.common.LocalRepositoryTestCase;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.test.ContextMenuHelper;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/trace/TraceConfigurationDialogTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/trace/TraceConfigurationDialogTest.java
index b8fa659..b383767 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/trace/TraceConfigurationDialogTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/test/trace/TraceConfigurationDialogTest.java
@@ -13,8 +13,8 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
-import org.eclipse.egit.ui.Activator;
 import org.eclipse.egit.ui.common.EGitTestCase;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.dialogs.GitTraceConfigurationDialog;
 import org.eclipse.jface.dialogs.IDialogConstants;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/variables/DynamicVariablesTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/variables/DynamicVariablesTest.java
index e787cd7..dabe86b 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/variables/DynamicVariablesTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/variables/DynamicVariablesTest.java
@@ -21,9 +21,9 @@
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.variables.IDynamicVariable;
 import org.eclipse.core.variables.VariablesPlugin;
-import org.eclipse.egit.core.GitProvider;
-import org.eclipse.egit.core.project.GitProjectData;
-import org.eclipse.egit.core.project.RepositoryMapping;
+import org.eclipse.egit.core.internal.GitProvider;
+import org.eclipse.egit.core.internal.project.GitProjectData;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
 import org.eclipse.egit.ui.common.EGitTestCase;
 import org.eclipse.jface.viewers.ISelectionProvider;
 import org.eclipse.jface.viewers.StructuredSelection;
@@ -132,7 +132,7 @@
 		repository.close();
 		repository2.close();
 
-		org.eclipse.egit.core.Activator.getDefault().getRepositoryCache().clear();
+		org.eclipse.egit.core.internal.Activator.getDefault().getRepositoryCache().clear();
 
 		FileUtils.delete(gitDir, FileUtils.RECURSIVE);
 		// gitDir2 is inside project, already gone
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewBranchHandlingTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewBranchHandlingTest.java
index 1a074c0..74a50fa 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewBranchHandlingTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewBranchHandlingTest.java
@@ -20,10 +20,10 @@
 import java.util.List;
 import java.util.concurrent.atomic.AtomicBoolean;
 
-import org.eclipse.egit.core.op.BranchOperation;
-import org.eclipse.egit.core.op.CloneOperation;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.core.internal.op.BranchOperation;
+import org.eclipse.egit.core.internal.op.CloneOperation;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.decorators.GitLightweightDecorator;
 import org.eclipse.egit.ui.test.ContextMenuHelper;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewFetchAndPushTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewFetchAndPushTest.java
index 4e71304..cdd91d8 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewFetchAndPushTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewFetchAndPushTest.java
@@ -16,9 +16,9 @@
 import java.io.File;
 import java.util.concurrent.TimeUnit;
 
-import org.eclipse.egit.core.op.CloneOperation;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.core.internal.op.CloneOperation;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.push.PushOperationUI;
 import org.eclipse.egit.ui.test.ContextMenuHelper;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewRemoteHandlingTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewRemoteHandlingTest.java
index 152ea45..d90080a 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewRemoteHandlingTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewRemoteHandlingTest.java
@@ -16,7 +16,7 @@
 import java.io.File;
 import java.util.List;
 
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.test.ContextMenuHelper;
 import org.eclipse.jface.dialogs.IDialogConstants;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewRepoDeletionTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewRepoDeletionTest.java
index 1c96195..6fa4dd0 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewRepoDeletionTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewRepoDeletionTest.java
@@ -13,8 +13,8 @@
 
 import java.io.File;
 
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.test.ContextMenuHelper;
 import org.eclipse.egit.ui.test.TestUtil;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewRepoHandlingTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewRepoHandlingTest.java
index 7ec0e51..873a295 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewRepoHandlingTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewRepoHandlingTest.java
@@ -19,7 +19,7 @@
 
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.test.ContextMenuHelper;
 import org.eclipse.egit.ui.test.TestUtil;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTagHandlingTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTagHandlingTest.java
index 9bb6f0d..2cb5e7d 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTagHandlingTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTagHandlingTest.java
@@ -20,8 +20,8 @@
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.Platform;
 import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.test.ContextMenuHelper;
 import org.eclipse.egit.ui.test.TestUtil;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTest.java
index 123b5d4..8117314 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTest.java
@@ -27,9 +27,9 @@
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.test.ContextMenuHelper;
 import org.eclipse.egit.ui.test.TestUtil;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTestBase.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTestBase.java
index 08026a6..1fa6ba6 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTestBase.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTestBase.java
@@ -29,12 +29,12 @@
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.Path;
 import org.eclipse.core.runtime.preferences.InstanceScope;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.RepositoryUtil;
-import org.eclipse.egit.core.op.CommitOperation;
-import org.eclipse.egit.core.op.ConnectProviderOperation;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.RepositoryUtil;
+import org.eclipse.egit.core.internal.op.CommitOperation;
+import org.eclipse.egit.core.internal.op.ConnectProviderOperation;
 import org.eclipse.egit.ui.common.LocalRepositoryTestCase;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.push.PushOperationUI;
 import org.eclipse.egit.ui.internal.repository.RepositoriesView;
@@ -161,7 +161,7 @@
 
 	protected static File createRemoteRepository(File repositoryDir)
 			throws Exception {
-		Repository myRepository = org.eclipse.egit.core.Activator.getDefault()
+		Repository myRepository = org.eclipse.egit.core.internal.Activator.getDefault()
 				.getRepositoryCache().lookupRepository(repositoryDir);
 		File gitDir = new File(getTestDirectory(), REPO2);
 		Repository myRemoteRepository = lookupRepository(gitDir);
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTestUtils.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTestUtils.java
index 59c5666..d6fb88c 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTestUtils.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/repositories/GitRepositoriesViewTestUtils.java
@@ -163,7 +163,7 @@
 	}
 
 	public Repository lookupRepository(File directory) throws Exception {
-		return org.eclipse.egit.core.Activator.getDefault()
+		return org.eclipse.egit.core.internal.Activator.getDefault()
 				.getRepositoryCache().lookupRepository(directory);
 	}
 
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/synchronize/AbstractSynchronizeViewTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/synchronize/AbstractSynchronizeViewTest.java
index 3233a89..26b4efe 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/synchronize/AbstractSynchronizeViewTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/synchronize/AbstractSynchronizeViewTest.java
@@ -35,14 +35,14 @@
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.core.op.CommitOperation;
-import org.eclipse.egit.core.op.ConnectProviderOperation;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.JobFamilies;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.core.internal.op.CommitOperation;
+import org.eclipse.egit.core.internal.op.ConnectProviderOperation;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeData;
 import org.eclipse.egit.ui.common.LocalRepositoryTestCase;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.JobFamilies;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.synchronize.GitModelSynchronize;
 import org.eclipse.egit.ui.test.JobJoiner;
 import org.eclipse.egit.ui.test.TestUtil;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/synchronize/SynchronizeViewPushTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/synchronize/SynchronizeViewPushTest.java
index 118b109..11bd63d 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/synchronize/SynchronizeViewPushTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/view/synchronize/SynchronizeViewPushTest.java
@@ -13,8 +13,8 @@
 
 import java.util.concurrent.TimeUnit;
 
-import org.eclipse.egit.core.op.FetchOperation;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.core.internal.op.FetchOperation;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.test.JobJoiner;
 import org.eclipse.jgit.lib.ConfigConstants;
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/wizards/clone/TestRepositoryServerProvider.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/wizards/clone/TestRepositoryServerProvider.java
index 9195d65..68a84ff 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/wizards/clone/TestRepositoryServerProvider.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/wizards/clone/TestRepositoryServerProvider.java
@@ -16,7 +16,7 @@
 import java.util.Collection;
 import java.util.List;
 
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.provisional.wizards.IRepositoryServerProvider;
 import org.eclipse.egit.ui.internal.provisional.wizards.RepositoryServerInfo;
 
diff --git a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/wizards/share/SharingWizardTest.java b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/wizards/share/SharingWizardTest.java
index a973aa9..b80220c 100644
--- a/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/wizards/share/SharingWizardTest.java
+++ b/org.eclipse.egit.ui.test/src/org/eclipse/egit/ui/wizards/share/SharingWizardTest.java
@@ -29,14 +29,14 @@
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.Path;
 import org.eclipse.core.runtime.QualifiedName;
-import org.eclipse.egit.core.op.DisconnectProviderOperation;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.core.internal.op.DisconnectProviderOperation;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
 import org.eclipse.egit.ui.common.ExistingOrNewPage;
 import org.eclipse.egit.ui.common.ExistingOrNewPage.Row;
 import org.eclipse.egit.ui.common.LocalRepositoryTestCase;
 import org.eclipse.egit.ui.common.SharingWizard;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.test.Eclipse;
 import org.eclipse.jface.dialogs.IDialogConstants;
diff --git a/org.eclipse.egit.ui/.settings/.api_filters b/org.eclipse.egit.ui/.settings/.api_filters
deleted file mode 100644
index 712f3cf..0000000
--- a/org.eclipse.egit.ui/.settings/.api_filters
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<component id="org.eclipse.egit.ui" version="2">
-    <resource path="src/org/eclipse/egit/ui/UIPreferences.java" type="org.eclipse.egit.ui.UIPreferences">
-        <filter id="338755678">
-            <message_arguments>
-                <message_argument value="org.eclipse.egit.ui.UIPreferences"/>
-                <message_argument value="COMMIT_DIALOG_PUSH_UPSTREAM"/>
-            </message_arguments>
-        </filter>
-    </resource>
-</component>
diff --git a/org.eclipse.egit.ui/META-INF/MANIFEST.MF b/org.eclipse.egit.ui/META-INF/MANIFEST.MF
index e7971fd..36354a7 100644
--- a/org.eclipse.egit.ui/META-INF/MANIFEST.MF
+++ b/org.eclipse.egit.ui/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@
 Bundle-Name: %plugin_name
 Bundle-SymbolicName: org.eclipse.egit.ui;singleton:=true
 Bundle-Version: 3.0.0.qualifier
-Bundle-Activator: org.eclipse.egit.ui.Activator
+Bundle-Activator: org.eclipse.egit.ui.internal.Activator
 Bundle-Vendor: %provider_name
 Bundle-Localization: plugin
 Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.7.0,4.0.0)",
@@ -32,17 +32,16 @@
  org.eclipse.debug.ui;bundle-version="[3.4.0,4.0.0)";resolution:=optional
 Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: J2SE-1.5
-Import-Package: org.eclipse.egit.core;version="[3.0.0,3.1.0)",
- org.eclipse.egit.core.internal;version="[3.0.0,3.1.0)",
+Import-Package: org.eclipse.egit.core.internal;version="[3.0.0,3.1.0)",
  org.eclipse.egit.core.internal.indexdiff;version="[3.0.0,3.1.0)",
  org.eclipse.egit.core.internal.job;version="[3.0.0,3.1.0)",
+ org.eclipse.egit.core.internal.op;version="[3.0.0,3.1.0)",
+ org.eclipse.egit.core.internal.project;version="[3.0.0,3.1.0)",
+ org.eclipse.egit.core.internal.securestorage;version="[3.0.0,3.1.0)",
  org.eclipse.egit.core.internal.storage;version="[3.0.0,3.1.0)",
+ org.eclipse.egit.core.internal.synchronize;version="[3.0.0,3.1.0)",
+ org.eclipse.egit.core.internal.synchronize.dto;version="[3.0.0,3.1.0)",
  org.eclipse.egit.core.internal.util;version="[3.0.0,3.1.0)",
- org.eclipse.egit.core.op;version="[3.0.0,3.1.0)",
- org.eclipse.egit.core.project;version="[3.0.0,3.1.0)",
- org.eclipse.egit.core.securestorage;version="[3.0.0,3.1.0)",
- org.eclipse.egit.core.synchronize;version="[3.0.0,3.1.0)",
- org.eclipse.egit.core.synchronize.dto;version="[3.0.0,3.1.0)",
  org.eclipse.jgit.api;version="[3.0.0,3.1.0)",
  org.eclipse.jgit.api.errors;version="[3.0.0,3.1.0)",
  org.eclipse.jgit.blame;version="[3.0.0,3.1.0)",
diff --git a/org.eclipse.egit.ui/plugin.xml b/org.eclipse.egit.ui/plugin.xml
index 7fe35f8..2bc14f4 100644
--- a/org.eclipse.egit.ui/plugin.xml
+++ b/org.eclipse.egit.ui/plugin.xml
@@ -4,7 +4,7 @@
    <extension-point id="commitMessageProvider" name="%CommitMessageProviderExtension-point.name" schema="schema/commitMessageProvider.exsd"/>
    <extension-point id="cloneSourceProvider" name="%CloneSourceProviderExtension-point.name" schema="schema/cloneSourceProvider.exsd"/>
    <extension point="org.eclipse.core.runtime.preferences">
-      <initializer class="org.eclipse.egit.ui.PluginPreferenceInitializer"/>
+      <initializer class="org.eclipse.egit.ui.internal.PluginPreferenceInitializer"/>
    </extension>
 
    <extension point="org.eclipse.ui.importWizards">
@@ -32,7 +32,7 @@
             objectClass="org.eclipse.core.resources.IProject"
             adaptable="true">
          <filter name="projectPersistentProperty"
-               value="org.eclipse.team.core.repository=org.eclipse.egit.core.GitProvider">
+               value="org.eclipse.team.core.repository=org.eclipse.egit.core.internal.GitProvider">
          </filter>
          <action
                class="org.eclipse.egit.ui.internal.actions.DisconnectAction"
@@ -84,7 +84,7 @@
             objectClass="org.eclipse.core.resources.IContainer"
             adaptable="true">
          <filter name="projectPersistentProperty"
-               value="org.eclipse.team.core.repository=org.eclipse.egit.core.GitProvider">
+               value="org.eclipse.team.core.repository=org.eclipse.egit.core.internal.GitProvider">
          </filter>
          <action
                class="org.eclipse.egit.ui.internal.actions.SynchronizeWorkspaceAction"
@@ -98,7 +98,7 @@
             id="org.eclipse.egit.ui.resourceContributions"
             objectClass="org.eclipse.core.resources.IResource">
          <filter name="projectPersistentProperty"
-               value="org.eclipse.team.core.repository=org.eclipse.egit.core.GitProvider">
+               value="org.eclipse.team.core.repository=org.eclipse.egit.core.internal.GitProvider">
          </filter>
          <action
                class="org.eclipse.egit.ui.internal.actions.UntrackAction"
@@ -241,7 +241,7 @@
          id="org.eclipse.egit.ui.fileContributions"
          objectClass="org.eclipse.core.resources.IFile">
          <filter name="projectPersistentProperty"
-               value="org.eclipse.team.core.repository=org.eclipse.egit.core.GitProvider">
+               value="org.eclipse.team.core.repository=org.eclipse.egit.core.internal.GitProvider">
          </filter>
          <action
                class="org.eclipse.egit.ui.internal.actions.CompareWithRevisionAction"
@@ -256,7 +256,7 @@
             objectClass="org.eclipse.core.resources.IFile">
          <filter
                name="projectPersistentProperty"
-               value="org.eclipse.team.core.repository=org.eclipse.egit.core.GitProvider">
+               value="org.eclipse.team.core.repository=org.eclipse.egit.core.internal.GitProvider">
          </filter>
          <action
                class="org.eclipse.egit.ui.internal.actions.ShowBlameAction"
@@ -487,7 +487,7 @@
 		<adapt type="org.eclipse.core.resources.IResource">
 			<test
 				property="org.eclipse.core.resources.projectPersistentProperty"
-				args="org.eclipse.team.core.repository, org.eclipse.egit.core.GitProvider">
+				args="org.eclipse.team.core.repository, org.eclipse.egit.core.internal.GitProvider">
 			</test>
 		</adapt>
 	    </enabledWhen>
@@ -1828,7 +1828,7 @@
    <extension
          point="org.eclipse.ui.perspectives">
       <perspective
-            class="org.eclipse.egit.ui.GitRepositoriesPerspectiveFactory"
+            class="org.eclipse.egit.ui.internal.GitRepositoriesPerspectiveFactory"
             icon="icons/obj16/gitrepository.gif"
             id="org.eclipse.egit.ui.GitRepositoryExploring"
             name="%GitRepositoryPerspective_name">
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/Activator.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/Activator.java
deleted file mode 100644
index 9cdc29d..0000000
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/Activator.java
+++ /dev/null
@@ -1,605 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2007,2010 Robin Rosenberg <robin.rosenberg@dewire.com>
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * Copyright (C) 2010, Mathias Kinzler <mathias.kinzler@sap.com>
- * Copyright (C) 2012, Matthias Sohn <matthias.sohn@sap.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.ui;
-
-import java.io.IOException;
-import java.net.Authenticator;
-import java.net.ProxySelector;
-import java.util.ArrayList;
-import java.util.Dictionary;
-import java.util.HashSet;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.eclipse.core.net.proxy.IProxyService;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.core.runtime.jobs.ISchedulingRule;
-import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.egit.core.RepositoryUtil;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.ui.internal.ConfigurationChecker;
-import org.eclipse.egit.ui.internal.UIText;
-import org.eclipse.egit.ui.internal.credentials.EGitCredentialsProvider;
-import org.eclipse.egit.ui.internal.trace.GitTraceLocation;
-import org.eclipse.jface.util.IPropertyChangeListener;
-import org.eclipse.jface.util.PropertyChangeEvent;
-import org.eclipse.jgit.events.IndexChangedEvent;
-import org.eclipse.jgit.events.IndexChangedListener;
-import org.eclipse.jgit.events.ListenerHandle;
-import org.eclipse.jgit.events.RepositoryEvent;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.transport.CredentialsProvider;
-import org.eclipse.jgit.transport.SshSessionFactory;
-import org.eclipse.jsch.core.IJSchService;
-import org.eclipse.osgi.service.debug.DebugOptions;
-import org.eclipse.osgi.service.debug.DebugOptionsListener;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.widgets.Display;
-import org.eclipse.ui.IWindowListener;
-import org.eclipse.ui.IWorkbenchWindow;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.plugin.AbstractUIPlugin;
-import org.eclipse.ui.statushandlers.StatusManager;
-import org.eclipse.ui.themes.ITheme;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-
-/**
- * This is a plugin singleton mostly controlling logging.
- */
-public class Activator extends AbstractUIPlugin implements DebugOptionsListener {
-
-	/**
-	 *  The one and only instance
-	 */
-	private static Activator plugin;
-
-	/**
-	 * Property listeners for plugin specific events
-	 */
-	private static List<IPropertyChangeListener> propertyChangeListeners =
-		new ArrayList<IPropertyChangeListener>(5);
-
-	/**
-	 * Property constant indicating the decorator configuration has changed.
-	 */
-	public static final String DECORATORS_CHANGED = "org.eclipse.egit.ui.DECORATORS_CHANGED"; //$NON-NLS-1$
-
-	/**
-	 * @return the {@link Activator} singleton.
-	 */
-	public static Activator getDefault() {
-		return plugin;
-	}
-
-	/**
-	 * @return the id of the egit ui plugin
-	 */
-	public static String getPluginId() {
-		return getDefault().getBundle().getSymbolicName();
-	}
-
-	/**
-	 * Handle an error. The error is logged. If <code>show</code> is
-	 * <code>true</code> the error is shown to the user.
-	 *
-	 * @param message 		a localized message
-	 * @param throwable
-	 * @param show
-	 */
-	public static void handleError(String message, Throwable throwable,
-			boolean show) {
-		handleIssue(IStatus.ERROR, message, throwable, show);
-	}
-
-	/**
-	 * Handle an issue. The issue is logged. If <code>show</code> is
-	 * <code>true</code> the issue is shown to the user.
-	 *
-	 * @param severity
-	 *            status severity, use constants defined in {@link IStatus}
-	 * @param message
-	 *            a localized message
-	 * @param throwable
-	 * @param show
-	 * @since 2.2
-	 */
-	public static void handleIssue(int severity, String message, Throwable throwable,
-			boolean show) {
-		IStatus status = new Status(severity, getPluginId(), message,
-				throwable);
-		int style = StatusManager.LOG;
-		if (show)
-			style |= StatusManager.SHOW;
-		StatusManager.getManager().handle(status, style);
-	}
-
-	/**
-	 * Shows an error. The error is NOT logged.
-	 *
-	 * @param message
-	 *            a localized message
-	 * @param throwable
-	 */
-	public static void showError(String message, Throwable throwable) {
-		IStatus status = new Status(IStatus.ERROR, getPluginId(), message,
-				throwable);
-		StatusManager.getManager().handle(status, StatusManager.SHOW);
-	}
-
-	/**
-	 * Shows an error. The error is NOT logged.
-	 *
-	 * @param message
-	 *            a localized message
-	 * @param status
-	 */
-	public static void showErrorStatus(String message, IStatus status) {
-		StatusManager.getManager().handle(status, StatusManager.SHOW);
-	}
-
-	/**
-	 * Get the theme used by this plugin.
-	 *
-	 * @return our theme.
-	 */
-	public static ITheme getTheme() {
-		return plugin.getWorkbench().getThemeManager().getCurrentTheme();
-	}
-
-	/**
-	 * Get a font known to this plugin.
-	 *
-	 * @param id
-	 *            one of our THEME_* font preference ids (see
-	 *            {@link UIPreferences});
-	 * @return the configured font, borrowed from the registry.
-	 */
-	public static Font getFont(final String id) {
-		return getTheme().getFontRegistry().get(id);
-	}
-
-	/**
-	 * Get a font known to this plugin, but with bold style applied over top.
-	 *
-	 * @param id
-	 *            one of our THEME_* font preference ids (see
-	 *            {@link UIPreferences});
-	 * @return the configured font, borrowed from the registry.
-	 */
-	public static Font getBoldFont(final String id) {
-		return getTheme().getFontRegistry().getBold(id);
-	}
-
-	private RepositoryChangeScanner rcs;
-	private ResourceRefreshJob refreshJob;
-	private ListenerHandle refreshHandle;
-	private DebugOptions debugOptions;
-
-	private IWindowListener focusListener;
-
-	/**
-	 * Construct the {@link Activator} egit ui plugin singleton instance
-	 */
-	public Activator() {
-		Activator.setActivator(this);
-	}
-
-	private static void setActivator(Activator a) {
-		plugin = a;
-	}
-
-
-	public void start(final BundleContext context) throws Exception {
-		super.start(context);
-
-		// we want to be notified about debug options changes
-		Dictionary<String, String> props = new Hashtable<String, String>(4);
-		props.put(DebugOptions.LISTENER_SYMBOLICNAME, context.getBundle()
-				.getSymbolicName());
-		context.registerService(DebugOptionsListener.class.getName(), this,
-				props);
-
-		setupSSH(context);
-		setupProxy(context);
-		setupRepoChangeScanner();
-		setupRepoIndexRefresh();
-		setupFocusHandling();
-		setupCredentialsProvider();
-		ConfigurationChecker.checkConfiguration();
-	}
-
-	private void setupCredentialsProvider() {
-		CredentialsProvider.setDefault(new EGitCredentialsProvider());
-	}
-
-	static boolean isActive() {
-		final AtomicBoolean ret = new AtomicBoolean();
-		final Display display = PlatformUI.getWorkbench().getDisplay();
-		if (display.isDisposed())
-			return false;
-		display.syncExec(new Runnable() {
-			public void run() {
-				ret.set(display.getActiveShell() != null);
-			}
-		});
-		return ret.get();
-	}
-
-	private void setupFocusHandling() {
-		focusListener = new IWindowListener() {
-
-			public void windowOpened(IWorkbenchWindow window) {
-				// nothing
-			}
-
-			public void windowDeactivated(IWorkbenchWindow window) {
-				// nothing
-			}
-
-			public void windowClosed(IWorkbenchWindow window) {
-				// nothing
-			}
-
-			public void windowActivated(IWorkbenchWindow window) {
-				if (rcs.doReschedule)
-					rcs.schedule();
-				refreshJob.triggerRefresh();
-			}
-		};
-		PlatformUI.getWorkbench().addWindowListener(focusListener);
-	}
-
-	public void optionsChanged(DebugOptions options) {
-		// initialize the trace stuff
-		debugOptions = options;
-		GitTraceLocation.initializeFromOptions(options, isDebugging());
-	}
-
-	/**
-	 * @return the {@link DebugOptions}
-	 */
-	public DebugOptions getDebugOptions() {
-		return debugOptions;
-	}
-
-	private void setupRepoIndexRefresh() {
-		refreshJob = new ResourceRefreshJob();
-		refreshHandle = Repository.getGlobalListenerList()
-				.addIndexChangedListener(refreshJob);
-	}
-
-	/**
-	 * Register for changes made to Team properties.
-	 *
-	 * @param listener
-	 *            The listener to register
-	 */
-	public static synchronized void addPropertyChangeListener(
-			IPropertyChangeListener listener) {
-		propertyChangeListeners.add(listener);
-	}
-
-	/**
-	 * Remove a Team property changes.
-	 *
-	 * @param listener
-	 *            The listener to remove
-	 */
-	public static synchronized void removePropertyChangeListener(
-			IPropertyChangeListener listener) {
-		propertyChangeListeners.remove(listener);
-	}
-
-	/**
-	 * Broadcast a Team property change.
-	 *
-	 * @param event
-	 *            The event to broadcast
-	 */
-	public static synchronized void broadcastPropertyChange(PropertyChangeEvent event) {
-		for (IPropertyChangeListener listener : propertyChangeListeners)
-			listener.propertyChange(event);
-	}
-
-	/**
-	 * Refresh projects in repositories that we suspect may have resource
-	 * changes.
-	 */
-	static class ResourceRefreshJob extends Job implements IndexChangedListener {
-
-		ResourceRefreshJob() {
-			super(UIText.Activator_refreshJobName);
-		}
-
-		private Set<IProject> projectsToScan = new LinkedHashSet<IProject>();
-		private Set<Repository> repositoriesChanged = new HashSet<Repository>();
-
-		@Override
-		protected IStatus run(IProgressMonitor monitor) {
-			IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
-			monitor.beginTask(UIText.Activator_refreshingProjects, projects.length);
-
-			while (projectsToScan.size() > 0) {
-				IProject p;
-				synchronized (projectsToScan) {
-					if (projectsToScan.size() == 0)
-						break;
-					Iterator<IProject> i = projectsToScan.iterator();
-					p = i.next();
-					i.remove();
-				}
-				ISchedulingRule rule = p.getWorkspace().getRuleFactory().refreshRule(p);
-				try {
-					getJobManager().beginRule(rule, monitor);
-					if(p.exists()) // handle missing projects after branch switch
-						p.refreshLocal(IResource.DEPTH_INFINITE, new SubProgressMonitor(monitor, 1));
-				} catch (CoreException e) {
-					handleError(UIText.Activator_refreshFailed, e, false);
-					return new Status(IStatus.ERROR, getPluginId(), e.getMessage());
-				} finally {
-					getJobManager().endRule(rule);
-				}
-			}
-			monitor.done();
-			return Status.OK_STATUS;
-		}
-
-		public void onIndexChanged(IndexChangedEvent e) {
-			if (Activator.getDefault().getPreferenceStore()
-					.getBoolean(UIPreferences.REFESH_ON_INDEX_CHANGE))
-				mayTriggerRefresh(e);
-		}
-
-		/**
-		 * Record which projects have changes. Initiate a resource refresh job
-		 * if the user settings allow it.
-		 *
-		 * @param e
-		 *            The {@link RepositoryEvent} that triggered this refresh
-		 */
-		private void mayTriggerRefresh(RepositoryEvent e) {
-			repositoriesChanged.add(e.getRepository());
-			if (!Activator.getDefault().getPreferenceStore()
-					.getBoolean(UIPreferences.REFESH_ONLY_WHEN_ACTIVE)
-					|| isActive())
-				triggerRefresh();
-		}
-
-		/**
-		 * Figure which projects belong to a repository, add them to a set of
-		 * project to refresh and schedule the refresh as a job.
-		 */
-		void triggerRefresh() {
-			if (GitTraceLocation.REPOSITORYCHANGESCANNER.isActive())
-				GitTraceLocation.getTrace().trace(
-						GitTraceLocation.REPOSITORYCHANGESCANNER.getLocation(),
-						"Triggered refresh"); //$NON-NLS-1$
-			IProject[] projects = ResourcesPlugin.getWorkspace().getRoot()
-					.getProjects();
-			Set<IProject> toRefresh = new HashSet<IProject>();
-			synchronized (repositoriesChanged) {
-				for (IProject p : projects) {
-					RepositoryMapping mapping = RepositoryMapping.getMapping(p);
-					if (mapping != null
-							&& repositoriesChanged.contains(mapping
-									.getRepository())) {
-						toRefresh.add(p);
-					}
-				}
-				repositoriesChanged.clear();
-			}
-			synchronized (projectsToScan) {
-				projectsToScan.addAll(toRefresh);
-			}
-			if (projectsToScan.size() > 0)
-				schedule();
-		}
-	}
-
-	/**
-	 * A Job that looks at the repository meta data and triggers a refresh of
-	 * the resources in the affected projects.
-	 */
-	static class RepositoryChangeScanner extends Job {
-		RepositoryChangeScanner() {
-			super(UIText.Activator_repoScanJobName);
-		}
-
-		// FIXME, need to be more intelligent about this to avoid too much work
-		private static final long REPO_SCAN_INTERVAL = 10000L;
-		// volatile in order to ensure thread synchronization
-		private volatile boolean doReschedule = true;
-
-		void setReschedule(boolean reschedule){
-			doReschedule = reschedule;
-		}
-
-		@Override
-		protected IStatus run(IProgressMonitor monitor) {
-			Repository[] repos = org.eclipse.egit.core.Activator.getDefault()
-					.getRepositoryCache().getAllRepositories();
-			if (repos.length == 0)
-				return Status.OK_STATUS;
-
-			// When people use Git from the command line a lot of changes
-			// may happen. Don't scan when inactive depending on the user's
-			// choice.
-
-			if (Activator.getDefault().getPreferenceStore()
-					.getBoolean(UIPreferences.REFESH_ONLY_WHEN_ACTIVE)) {
-				if (!isActive()) {
-					monitor.done();
-					if (doReschedule)
-						schedule(REPO_SCAN_INTERVAL);
-					return Status.OK_STATUS;
-				}
-			}
-
-			monitor.beginTask(UIText.Activator_scanningRepositories,
-					repos.length);
-			try {
-				for (Repository repo : repos) {
-					if (monitor.isCanceled())
-						break;
-					if (GitTraceLocation.REPOSITORYCHANGESCANNER.isActive())
-						GitTraceLocation.getTrace().trace(
-								GitTraceLocation.REPOSITORYCHANGESCANNER
-										.getLocation(),
-								"Scanning " + repo + " for changes"); //$NON-NLS-1$ //$NON-NLS-2$
-
-					repo.scanForRepoChanges();
-					monitor.worked(1);
-				}
-			} catch (IOException e) {
-				if (GitTraceLocation.REPOSITORYCHANGESCANNER.isActive())
-					GitTraceLocation.getTrace().trace(
-							GitTraceLocation.REPOSITORYCHANGESCANNER
-									.getLocation(),
-							"Stopped rescheduling " + getName() + "job"); //$NON-NLS-1$ //$NON-NLS-2$
-				return createErrorStatus(UIText.Activator_scanError, e);
-			} finally {
-				monitor.done();
-			}
-			if (GitTraceLocation.REPOSITORYCHANGESCANNER.isActive())
-				GitTraceLocation.getTrace().trace(
-						GitTraceLocation.REPOSITORYCHANGESCANNER.getLocation(),
-						"Rescheduling " + getName() + " job"); //$NON-NLS-1$ //$NON-NLS-2$
-			if (doReschedule)
-				schedule(REPO_SCAN_INTERVAL);
-			return Status.OK_STATUS;
-		}
-	}
-
-	private void setupRepoChangeScanner() {
-		rcs = new RepositoryChangeScanner();
-		rcs.setSystem(true);
-		rcs.schedule(RepositoryChangeScanner.REPO_SCAN_INTERVAL);
-	}
-
-	private void setupSSH(final BundleContext context) {
-		final ServiceReference ssh;
-
-		ssh = context.getServiceReference(IJSchService.class.getName());
-		if (ssh != null) {
-			SshSessionFactory.setInstance(new EclipseSshSessionFactory(
-					(IJSchService) context.getService(ssh)));
-		}
-	}
-
-	private void setupProxy(final BundleContext context) {
-		final ServiceReference proxy;
-
-		proxy = context.getServiceReference(IProxyService.class.getName());
-		if (proxy != null) {
-			ProxySelector.setDefault(new EclipseProxySelector(
-					(IProxyService) context.getService(proxy)));
-			Authenticator.setDefault(new EclipseAuthenticator(
-					(IProxyService) context.getService(proxy)));
-		}
-	}
-
-	public void stop(final BundleContext context) throws Exception {
-		if (refreshHandle != null) {
-			refreshHandle.remove();
-			refreshHandle = null;
-		}
-
-		if (focusListener != null) {
-			PlatformUI.getWorkbench().removeWindowListener(focusListener);
-			focusListener = null;
-		}
-
-		if (GitTraceLocation.REPOSITORYCHANGESCANNER.isActive())
-			GitTraceLocation.getTrace().trace(
-					GitTraceLocation.REPOSITORYCHANGESCANNER.getLocation(),
-					"Trying to cancel " + rcs.getName() + " job"); //$NON-NLS-1$ //$NON-NLS-2$
-
-		rcs.setReschedule(false);
-
-		rcs.cancel();
-		if (GitTraceLocation.REPOSITORYCHANGESCANNER.isActive())
-			GitTraceLocation.getTrace().trace(
-					GitTraceLocation.REPOSITORYCHANGESCANNER.getLocation(),
-					"Trying to cancel " + refreshJob.getName() + " job"); //$NON-NLS-1$ //$NON-NLS-2$
-		refreshJob.cancel();
-
-		rcs.join();
-		refreshJob.join();
-
-		if (GitTraceLocation.REPOSITORYCHANGESCANNER.isActive())
-			GitTraceLocation.getTrace().trace(
-					GitTraceLocation.REPOSITORYCHANGESCANNER.getLocation(),
-					"Jobs terminated"); //$NON-NLS-1$
-
-		super.stop(context);
-		plugin = null;
-	}
-
-	/**
-	 * @param message
-	 * @param e
-	 */
-	public static void logError(String message, Throwable e) {
-		handleError(message, e, false);
-	}
-
-	/**
-	 * @param message
-	 * @param e
-	 */
-	public static void error(String message, Throwable e) {
-		handleError(message, e, false);
-	}
-
-	/**
-	 * Creates an error status
-	 *
-	 * @param message
-	 *            a localized message
-	 * @param throwable
-	 * @return a new Status object
-	 */
-	public static IStatus createErrorStatus(String message, Throwable throwable) {
-		return new Status(IStatus.ERROR, getPluginId(), message, throwable);
-	}
-
-	/**
-	 * Creates an error status
-	 *
-	 * @param message
-	 *            a localized message
-	 * @return a new Status object
-	 */
-	public static IStatus createErrorStatus(String message) {
-		return new Status(IStatus.ERROR, getPluginId(), message);
-	}
-
-	/**
-	 * @return the {@link RepositoryUtil} instance
-	 */
-	public RepositoryUtil getRepositoryUtil() {
-		return org.eclipse.egit.core.Activator.getDefault().getRepositoryUtil();
-	}
-
-}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/EclipseAuthenticator.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/EclipseAuthenticator.java
deleted file mode 100644
index 0aebe09..0000000
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/EclipseAuthenticator.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.ui;
-
-import java.net.Authenticator;
-import java.net.InetAddress;
-import java.net.PasswordAuthentication;
-import java.net.UnknownHostException;
-
-import org.eclipse.core.net.proxy.IProxyData;
-import org.eclipse.core.net.proxy.IProxyService;
-
-class EclipseAuthenticator extends Authenticator {
-	private final IProxyService service;
-
-	EclipseAuthenticator(final IProxyService s) {
-		service = s;
-	}
-
-	@Override
-	protected PasswordAuthentication getPasswordAuthentication() {
-		final IProxyData[] data = service.getProxyData();
-		if (data == null)
-			return null;
-		for (final IProxyData d : data) {
-			if (d.getUserId() == null || d.getHost() == null)
-				continue;
-			if (d.getPort() == getRequestingPort() && hostMatches(d))
-				return auth(d);
-		}
-		return null;
-	}
-
-	private PasswordAuthentication auth(final IProxyData d) {
-		final String user = d.getUserId();
-		final String pass = d.getPassword();
-		final char[] passChar = pass != null ? pass.toCharArray() : new char[0];
-		return new PasswordAuthentication(user, passChar);
-	}
-
-	private boolean hostMatches(final IProxyData d) {
-		try {
-			final InetAddress dHost = InetAddress.getByName(d.getHost());
-			InetAddress rHost = getRequestingSite();
-			if (rHost == null)
-				rHost = InetAddress.getByName(getRequestingHost());
-			return dHost.equals(rHost);
-		} catch (UnknownHostException err) {
-			return false;
-		}
-	}
-}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/EclipseProxySelector.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/EclipseProxySelector.java
deleted file mode 100644
index 156dd8c..0000000
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/EclipseProxySelector.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.ui;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.Proxy;
-import java.net.ProxySelector;
-import java.net.SocketAddress;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.eclipse.core.net.proxy.IProxyData;
-import org.eclipse.core.net.proxy.IProxyService;
-
-class EclipseProxySelector extends ProxySelector {
-	private final IProxyService service;
-
-	EclipseProxySelector(final IProxyService s) {
-		service = s;
-	}
-
-	@Override
-	public List<Proxy> select(final URI uri) {
-		final ArrayList<Proxy> r = new ArrayList<Proxy>();
-		final String host = uri.getHost();
-
-		if (host != null) {
-			String type = IProxyData.SOCKS_PROXY_TYPE;
-			if ("http".equals(uri.getScheme())) //$NON-NLS-1$
-				type = IProxyData.HTTP_PROXY_TYPE;
-			else if ("ftp".equals(uri.getScheme())) //$NON-NLS-1$
-				type = IProxyData.HTTP_PROXY_TYPE;
-			else if ("https".equals(uri.getScheme())) //$NON-NLS-1$
-				type = IProxyData.HTTPS_PROXY_TYPE;
-			try {
-				URI queryUri = new URI(type, "//" + host, null); //$NON-NLS-1$
-				final IProxyData[] dataArray = service.select(queryUri);
-				for (IProxyData data : dataArray) {
-					if (IProxyData.HTTP_PROXY_TYPE.equals(data.getType()))
-						addProxy(r, Proxy.Type.HTTP, data);
-					else if (IProxyData.HTTPS_PROXY_TYPE.equals(data.getType()))
-						addProxy(r, Proxy.Type.HTTP, data);
-					else if (IProxyData.SOCKS_PROXY_TYPE.equals(data.getType()))
-						addProxy(r, Proxy.Type.SOCKS, data);
-				}
-			} catch (URISyntaxException e) {
-				// just add nothing to r
-			}
-		}
-		if (r.isEmpty())
-			r.add(Proxy.NO_PROXY);
-		return r;
-	}
-
-	private void addProxy(final ArrayList<Proxy> r, final Proxy.Type type,
-			final IProxyData d) {
-		try {
-			r.add(new Proxy(type, new InetSocketAddress(InetAddress.getByName(d
-					.getHost()), d.getPort())));
-		} catch (UnknownHostException uhe) {
-			// Oh well.
-		}
-	}
-
-	@Override
-	public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
-		// Don't tell Eclipse.
-	}
-}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/EclipseSshSessionFactory.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/EclipseSshSessionFactory.java
deleted file mode 100644
index d2d8cc3..0000000
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/EclipseSshSessionFactory.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * Copyright (C) 2009, Google, Inc.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.ui;
-
-import org.eclipse.jgit.transport.JschConfigSessionFactory;
-import org.eclipse.jgit.transport.OpenSshConfig;
-import org.eclipse.jgit.util.FS;
-import org.eclipse.jsch.core.IJSchService;
-import org.eclipse.jsch.ui.UserInfoPrompter;
-
-import com.jcraft.jsch.JSch;
-import com.jcraft.jsch.JSchException;
-import com.jcraft.jsch.Session;
-import com.jcraft.jsch.UserInfo;
-
-class EclipseSshSessionFactory extends JschConfigSessionFactory {
-	private final IJSchService provider;
-
-	EclipseSshSessionFactory(final IJSchService p) {
-		provider = p;
-	}
-
-	@Override
-	protected JSch createDefaultJSch(FS fs) throws JSchException {
-		// Forcing a dummy session to be created will cause the known hosts
-		// and configured private keys to be initialized. This is needed by
-		// our parent class in case non-default JSch instances need to be made.
-		//
-		provider.createSession("127.0.0.1", 0, "eclipse"); //$NON-NLS-1$ //$NON-NLS-2$
-		return provider.getJSch();
-	}
-
-	@Override
-	protected Session createSession(final OpenSshConfig.Host hc,
-			final String user, final String host, final int port, FS fs)
-			throws JSchException {
-		final JSch jsch = getJSch(hc, FS.DETECTED);
-		if (jsch == provider.getJSch()) {
-			// If its the default JSch desired, let the provider
-			// manage the session creation for us.
-			//
-			return provider.createSession(host, port, user);
-		} else {
-			// This host configuration is using a different IdentityFile,
-			// one that is not available through the default JSch.
-			//
-			return jsch.getSession(user, host, port);
-		}
-	}
-
-	@Override
-	protected void configure(final OpenSshConfig.Host hc, final Session session) {
-		UserInfo userInfo = session.getUserInfo();
-		if (!hc.isBatchMode() && userInfo == null)
-			new UserInfoPrompter(session);
-	}
-}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/GitRepositoriesPerspectiveFactory.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/GitRepositoriesPerspectiveFactory.java
deleted file mode 100644
index 6d7e7ae..0000000
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/GitRepositoriesPerspectiveFactory.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010, 2011 SAP AG and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *    Mathias Kinzler (SAP AG) - initial implementation
- *    Daniel Megert <daniel_megert@ch.ibm.com> - EGit must not pollute toolbars of perspectives it doesn't own - http://bugs.eclipse.org/356554
- *******************************************************************************/
-package org.eclipse.egit.ui;
-
-import org.eclipse.egit.ui.internal.reflog.ReflogView;
-import org.eclipse.egit.ui.internal.repository.RepositoriesView;
-import org.eclipse.egit.ui.internal.staging.StagingView;
-import org.eclipse.team.ui.history.IHistoryView;
-import org.eclipse.team.ui.synchronize.ISynchronizeView;
-import org.eclipse.ui.IFolderLayout;
-import org.eclipse.ui.IPageLayout;
-import org.eclipse.ui.IPerspectiveFactory;
-
-/**
- * Git Repository Exploring perspective factory
- */
-public class GitRepositoriesPerspectiveFactory implements IPerspectiveFactory {
-
-	public void createInitialLayout(IPageLayout layout) {
-
-		// repositories on the left hand
-		layout.addView(RepositoriesView.VIEW_ID, IPageLayout.LEFT, (float) 0.5, layout.getEditorArea());
-
-		IFolderLayout bottom = layout.createFolder(
-				"bottom", IPageLayout.BOTTOM, (float) 0.5, //$NON-NLS-1$
-				layout.getEditorArea());
-
-		// Views under editor area
-		bottom.addView(IPageLayout.ID_PROP_SHEET);
-		bottom.addView(IHistoryView.VIEW_ID);
-		bottom.addView(ISynchronizeView.VIEW_ID);
-		bottom.addView(StagingView.VIEW_ID);
-		bottom.addView(ReflogView.VIEW_ID);
-
-		// place holder for Package Explorer under repositories
-		layout.addPlaceholder("org.eclipse.jdt.ui.PackageExplorer", IPageLayout.BOTTOM, (float) 0.7, RepositoriesView.VIEW_ID); //$NON-NLS-1$
-
-		// shortcut to Package Explorer
-		layout.addShowViewShortcut("org.eclipse.jdt.ui.PackageExplorer"); //$NON-NLS-1$
-		// shortcut to History view
-		layout.addShowViewShortcut(IHistoryView.VIEW_ID);
-		// shortcut to Synchronize view
-		layout.addShowViewShortcut(ISynchronizeView.VIEW_ID);
-		// shortcut to Staging view
-		layout.addShowViewShortcut(StagingView.VIEW_ID);
-		// shortcut to Reflog view
-		layout.addShowViewShortcut(ReflogView.VIEW_ID);
-
-		layout.addActionSet("org.eclipse.egit.ui.navigation"); //$NON-NLS-1$
-	}
-
-}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/JobFamilies.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/JobFamilies.java
deleted file mode 100644
index f0bfc87..0000000
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/JobFamilies.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2010, Jens Baumgart <jens.baumgart@sap.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.ui;
-
-/**
- * Job families of EGit jobs. May be used in tests to join job execution.
- *
- */
-public class JobFamilies {
-	/**
-	 * GenerateHistoryJob
-	 */
-	public final static Object GENERATE_HISTORY = new Object();
-
-	/**
-	 * Commit job
-	 */
-	public final static Object COMMIT = new Object();
-
-	/**
-	 * Checkout job
-	 */
-	public final static Object CHECKOUT = new Object();
-
-	/**
-	 * Push job
-	 */
-	public final static Object PUSH = new Object();
-
-	/**
-	 * Fetch job
-	 */
-	public final static Object FETCH = new Object();
-
-	/**
-	 * Repositories View refresh
-	 */
-	public final static Object REPO_VIEW_REFRESH = new Object();
-
-	/**
-	 * Delete repository job
-	 */
-	public final static Object REPOSITORY_DELETE = new Object();
-
-	/**
-	 * Tag job
-	 */
-	public final static Object TAG = new Object();
-
-	/**
-	 * Reset job
-	 */
-	public static final Object RESET = new Object();
-
-	/**
-	 * Rebase job
-	 */
-	public static final Object REBASE = new Object();
-
-	/**
-	 * Pull job
-	 */
-	public final static Object PULL = new Object();
-
-	/**
-	 * Format job
-	 */
-	public final static Object FORMAT_COMMIT_INFO = new Object();
-
-	/**
-	 * Fill tag list
-	 */
-	public final static Object FILL_TAG_LIST = new Object();
-
-	/**
-	 * AssumeUnchanged/NoAssumeUnchanged
-	 */
-	public final static Object ASSUME_NOASSUME_UNCHANGED = new Object();
-
-	/**
-	 * Untrack
-	 */
-	public final static Object UNTRACK = new Object();
-
-	/**
-	 * Disconnect
-	 */
-	public final static Object DISCONNECT = new Object();
-
-	/**
-	 * Discard Changes
-	 */
-	public final static Object DISCARD_CHANGES = new Object();
-
-
-	/**
-	 * Add to index job
-	 */
-	public static final Object ADD_TO_INDEX = new Object();
-
-	/**
-	 * Remove from index job
-	 */
-	public static final Object REMOVE_FROM_INDEX = new Object();
-
-	/**
-	 * Cherry pick commit job
-	 */
-	public static final Object CHERRY_PICK = new Object();
-
-	/**
-	 * Revert commit job
-	 */
-	public static final Object REVERT_COMMIT = new Object();
-
-	/**
-	 * Clone repository job
-	 */
-	public static final Object CLONE = new Object();
-
-	/**
-	 * Fetch data from git job
-	 */
-	public static final Object SYNCHRONIZE_READ_DATA = new Object();
-
-	/**
-	 * Show annotations git job
-	 */
-	public static final Object BLAME = new Object();
-
-	/**
-	 * Submodule add git job
-	 */
-	public static final Object SUBMODULE_ADD = new Object();
-
-	/**
-	 * Submodule sync git job
-	 */
-	public static final Object SUBMODULE_SYNC = new Object();
-
-	/**
-	 * Submodule update git job
-	 */
-	public static final Object SUBMODULE_UPDATE = new Object();
-
-	/**
-	 * Stash git job
-	 */
-	public static final Object STASH = new Object();
-}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/PluginPreferenceInitializer.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/PluginPreferenceInitializer.java
deleted file mode 100644
index f5dc979..0000000
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/PluginPreferenceInitializer.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2008, Roger C. Soares <rogersoares@intelinet.com.br>
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * Copyright (C) 2010, Mathias Kinzler <mathias.kinzler@sap.com>
- * Copyright (C) 2012, Daniel Megert <daniel_megert@ch.ibm.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.ui;
-
-import java.io.File;
-
-import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
-import org.eclipse.egit.ui.internal.decorators.GitLightweightDecorator;
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.jgit.util.FS;
-
-/**
- * Plugin extension point to initialize the plugin runtime preferences.
- */
-public class PluginPreferenceInitializer extends AbstractPreferenceInitializer {
-
-	/**
-	 * Calls super constructor.
-	 */
-	public PluginPreferenceInitializer() {
-		super();
-	}
-
-	/**
-	 * This method initializes the plugin preferences with default values.
-	 */
-	public void initializeDefaultPreferences() {
-		IPreferenceStore store = Activator.getDefault().getPreferenceStore();
-		int[] w;
-
-		store.setDefault(UIPreferences.RESOURCEHISTORY_SHOW_RELATIVE_DATE, true);
-		store.setDefault(UIPreferences.RESOURCEHISTORY_SHOW_EMAIL_ADDRESSES, true);
-		store.setDefault(UIPreferences.RESOURCEHISTORY_SHOW_NOTES, false);
-		store.setDefault(UIPreferences.RESOURCEHISTORY_SHOW_COMMENT_WRAP, true);
-		store.setDefault(UIPreferences.RESOURCEHISTORY_SHOW_REV_DETAIL, true);
-		store.setDefault(UIPreferences.RESOURCEHISTORY_SHOW_REV_COMMENT, true);
-		store.setDefault(UIPreferences.RESOURCEHISTORY_SHOW_TOOLTIPS, false);
-		store.setDefault(UIPreferences.RESOURCEHISTORY_SHOW_ALL_BRANCHES, false);
-		store.setDefault(UIPreferences.RESOURCEHISTORY_SHOW_ADDITIONAL_REFS, true);
-		store.setDefault(UIPreferences.RESOURCEHISTORY_FOLLOW_RENAMES, false);
-		store.setDefault(UIPreferences.RESOURCEHISTORY_COMPARE_MODE, false);
-
-		store.setDefault(UIPreferences.DECORATOR_RECOMPUTE_ANCESTORS, true);
-		store.setDefault(UIPreferences.DECORATOR_FILETEXT_DECORATION,
-				GitLightweightDecorator.DecorationHelper.FILE_FORMAT_DEFAULT);
-		store.setDefault(UIPreferences.DECORATOR_FOLDERTEXT_DECORATION,
-				GitLightweightDecorator.DecorationHelper.FOLDER_FORMAT_DEFAULT);
-		store.setDefault(UIPreferences.DECORATOR_PROJECTTEXT_DECORATION,
-				GitLightweightDecorator.DecorationHelper.PROJECT_FORMAT_DEFAULT);
-		store.setDefault(UIPreferences.DECORATOR_SHOW_TRACKED_ICON, true);
-		store.setDefault(UIPreferences.DECORATOR_SHOW_UNTRACKED_ICON, true);
-		store.setDefault(UIPreferences.DECORATOR_SHOW_STAGED_ICON, true);
-		store.setDefault(UIPreferences.DECORATOR_SHOW_CONFLICTS_ICON, true);
-		store.setDefault(UIPreferences.DECORATOR_SHOW_ASSUME_VALID_ICON, true);
-		store.setDefault(UIPreferences.DECORATOR_SHOW_DIRTY_ICON, false);
-
-		w = new int[] { 500, 500 };
-		store.setDefault(UIPreferences.RESOURCEHISTORY_GRAPH_SPLIT, UIPreferences.intArrayToString(w));
-		w = new int[] { 700, 300 };
-		store.setDefault(UIPreferences.RESOURCEHISTORY_REV_SPLIT, UIPreferences.intArrayToString(w));
-
-		store.setDefault(UIPreferences.FINDTOOLBAR_IGNORE_CASE, true);
-		store.setDefault(UIPreferences.FINDTOOLBAR_FIND_IN, 2);
-		store.setDefault(UIPreferences.COMMIT_DIALOG_HARD_WRAP_MESSAGE, true);
-		store.setDefault(UIPreferences.COMMIT_DIALOG_SIGNED_OFF_BY, false);
-
-		store.setDefault(UIPreferences.REFESH_ON_INDEX_CHANGE, true);
-		store.setDefault(UIPreferences.REFESH_ONLY_WHEN_ACTIVE, true);
-		store.setDefault(UIPreferences.DEFAULT_REPO_DIR, new File(FS.DETECTED.userHome(), "git").getPath()); //$NON-NLS-1$
-		store.setDefault(UIPreferences.SHOW_REBASE_CONFIRM, true);
-		store.setDefault(UIPreferences.SHOW_INITIAL_CONFIG_DIALOG, true);
-		store.setDefault(UIPreferences.SHOW_HOME_DIR_WARNING, true);
-		store.setDefault(UIPreferences.SHOW_GIT_PREFIX_WARNING, true);
-		store.setDefault(UIPreferences.SHOW_DETACHED_HEAD_WARNING, true);
-
-
-		store.setDefault(UIPreferences.SYNC_VIEW_CHANGESET_LABEL_FORMAT,
-				UIPreferences.DEFAULT_CHANGESET_FORMAT);
-		store.setDefault(UIPreferences.SYNC_VIEW_ALWAYS_SHOW_CHANGESET_MODEL,
-				false);
-		store.setDefault(UIPreferences.SYNC_VIEW_FETCH_BEFORE_LAUNCH, true);
-		store.setDefault(UIPreferences.DATE_FORMAT,
-				UIPreferences.DEFAULT_DATE_FORMAT);
-		store.setDefault(UIPreferences.HISTORY_MAX_NUM_COMMITS, 10000);
-		store.setDefault(UIPreferences.HISTORY_SHOW_TAG_SEQUENCE, false);
-		store.setDefault(UIPreferences.BLAME_IGNORE_WHITESPACE, false);
-		store.setDefault(UIPreferences.REMOTE_CONNECTION_TIMEOUT, 30 /* seconds */);
-		store.setDefault(UIPreferences.STAGING_VIEW_FILENAME_MODE, true);
-		store.setDefault(UIPreferences.CLONE_WIZARD_STORE_SECURESTORE, false);
-		store.setDefault(UIPreferences.COMMIT_DIALOG_HISTORY_SIZE, 10);
-		store.setDefault(UIPreferences.CHECKOUT_PROJECT_RESTORE, true);
-		store.setDefault(UIPreferences.HISTORY_MAX_TAG_LENGTH, 15);
-		store.setDefault(UIPreferences.HISTORY_MAX_BRANCH_LENGTH, 15);
-		store.setDefault(UIPreferences.CLONE_WIZARD_SHOW_DETAILED_FAILURE_DIALOG, true);
-	}
-
-}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIPreferences.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIPreferences.java
deleted file mode 100644
index 89db482..0000000
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIPreferences.java
+++ /dev/null
@@ -1,228 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
- * Copyright (C) 2008, Roger C. Soares <rogersoares@intelinet.com.br>
- * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
- * Copyright (C) 2010, Mathias Kinzler <mathias.kinzler@sap.com>
- * Copyright (C) 2012, Daniel Megert <daniel_megert@ch.ibm.com>
- * Copyright (C) 2013, Tobias Pfeifer <to.pfeifer@sap.com>
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *******************************************************************************/
-package org.eclipse.egit.ui;
-
-
-
-/**
- * Preferences used by the EGit UI plug-in.
- * <p>
- * All plug-in preferences shall be referenced by a constant in this class.
- */
-public class UIPreferences {
-	/** */
-	public final static String RESOURCEHISTORY_SHOW_RELATIVE_DATE = "resourcehistory_show_relative_date"; //$NON-NLS-1$
-	/** */
-	public final static String RESOURCEHISTORY_SHOW_EMAIL_ADDRESSES = "resourcehistory_show_email_addresses"; //$NON-NLS-1$
-	/** */
-	public final static String RESOURCEHISTORY_SHOW_NOTES = "resourcehistory_show_notes"; //$NON-NLS-1$
-	/** */
-	public final static String RESOURCEHISTORY_SHOW_COMMENT_WRAP = "resourcehistory_show_comment_wrap"; //$NON-NLS-1$
-	/** */
-	public static final String RESOURCEHISTORY_SHOW_COMMENT_FILL = "resourcehistory_fill_comment_paragraph"; //$NON-NLS-1$
-	/** */
-	public final static String RESOURCEHISTORY_SHOW_REV_DETAIL = "resourcehistory_show_rev_detail"; //$NON-NLS-1$
-	/** */
-	public final static String RESOURCEHISTORY_SHOW_REV_COMMENT = "resourcehistory_show_rev_comment"; //$NON-NLS-1$
-	/** */
-	public final static String RESOURCEHISTORY_GRAPH_SPLIT = "resourcehistory_graph_split"; //$NON-NLS-1$
-	/** */
-	public final static String RESOURCEHISTORY_REV_SPLIT = "resourcehistory_rev_split"; //$NON-NLS-1$
-	/** */
-	public final static String RESOURCEHISTORY_SHOW_TOOLTIPS = "resourcehistory_show_tooltips"; //$NON-NLS-1$
-	/** */
-	public final static String RESOURCEHISTORY_SHOW_FINDTOOLBAR = "resourcehistory_show_findtoolbar"; //$NON-NLS-1$
-	/** */
-	public final static String RESOURCEHISTORY_SHOW_ALL_BRANCHES = "resourcehistory_show_all_branches"; //$NON-NLS-1$
-	/** */
-	public final static String RESOURCEHISTORY_SHOW_ADDITIONAL_REFS = "resourcehistory_show_additionalrefs"; //$NON-NLS-1$
-	/** */
-	public static final String RESOURCEHISTORY_FOLLOW_RENAMES = "resourcehistory_follow_renames"; //$NON-NLS-1$
-	/** */
-	public final static String RESOURCEHISTORY_COMPARE_MODE = "resourcehistory_compare_mode"; //$NON-NLS-1$
-	/** */
-	public final static String FINDTOOLBAR_IGNORE_CASE = "findtoolbar_ignore_case"; //$NON-NLS-1$
-	/** */
-	public final static String FINDTOOLBAR_COMMIT_ID = "findtoolbar_commit_id"; //$NON-NLS-1$
-	/** */
-	public final static String FINDTOOLBAR_COMMENTS = "findtoolbar_comments"; //$NON-NLS-1$
-	/** */
-	public final static String FINDTOOLBAR_AUTHOR = "findtoolbar_author"; //$NON-NLS-1$
-	/** */
-	public final static String FINDTOOLBAR_COMMITTER = "findtoolbar_committer"; //$NON-NLS-1$
-	/** */
-	public final static String FINDTOOLBAR_FIND_IN = "findtoolbar_find_in"; //$NON-NLS-1$
-	/** */
-	public final static String COMMIT_DIALOG_HARD_WRAP_MESSAGE = "commit_dialog_hard_wrap_message"; //$NON-NLS-1$
-	/** */
-	public final static String COMMIT_DIALOG_SIGNED_OFF_BY = "commit_dialog_signed_off_by"; //$NON-NLS-1$
-	/** */
-	public final static String COMMIT_DIALOG_HISTORY_SIZE = "commit_dialog_history_size"; //$NON-NLS-1$
-	/** */
-	public final static String COMMIT_DIALOG_HISTORY_MESSAGES = "commit_dialog_history_messages"; //$NON-NLS-1$
-	/** */
-	public final static String COMMIT_DIALOG_INCLUDE_UNTRACKED = "commit_dialog_include_untracked"; //$NON-NLS-1$
-	/** */
-	public final static String CHECKOUT_PROJECT_RESTORE = "restore_projects_on_checkout"; //$NON-NLS-1$
-	/** */
-	public final static String THEME_CommitGraphNormalFont = "org.eclipse.egit.ui.CommitGraphNormalFont"; //$NON-NLS-1$
-	/** */
-	public final static String THEME_CommitGraphHighlightFont = "org.eclipse.egit.ui.CommitGraphHighlightFont"; //$NON-NLS-1$
-	/** */
-	public final static String THEME_CommitMessageFont = "org.eclipse.egit.ui.CommitMessageFont"; //$NON-NLS-1$
-	/** */
-	public final static String THEME_CommitMessageEditorFont = "org.eclipse.egit.ui.CommitMessageEditorFont"; //$NON-NLS-1$
-	/** */
-	public final static String THEME_UncommittedChangeForegroundColor = "org.eclipse.egit.ui.UncommittedChangeForegroundColor"; //$NON-NLS-1$
-	/** */
-	public final static String THEME_UncommittedChangeBackgroundColor = "org.eclipse.egit.ui.UncommittedChangeBackgroundColor"; //$NON-NLS-1$
-	/** */
-	public final static String THEME_UncommittedChangeFont = "org.eclipse.egit.ui.UncommittedChangeFont"; //$NON-NLS-1$
-	/** */
-	public final static String THEME_DiffHunkBackgroundColor = "org.eclipse.egit.ui.DiffHunkBackgroundColor"; //$NON-NLS-1$
-	/** */
-	public final static String THEME_DiffHunkForegroundColor = "org.eclipse.egit.ui.DiffHunkForegroundColor"; //$NON-NLS-1$
-	/** */
-	public final static String THEME_DiffHeadlineBackgroundColor = "org.eclipse.egit.ui.DiffHeadlineBackgroundColor"; //$NON-NLS-1$
-	/** */
-	public final static String THEME_DiffHeadlineForegroundColor = "org.eclipse.egit.ui.DiffHeadlineForegroundColor"; //$NON-NLS-1$
-	/** */
-	public final static String THEME_DiffHeadlineFont = "org.eclipse.egit.ui.DiffHeadlineFont"; //$NON-NLS-1$
-	/** */
-	public final static String THEME_DiffAddBackgroundColor = "org.eclipse.egit.ui.DiffAddBackgroundColor"; //$NON-NLS-1$
-	/** */
-	public final static String THEME_DiffAddForegroundColor = "org.eclipse.egit.ui.DiffAddForegroundColor"; //$NON-NLS-1$
-	/** */
-	public final static String THEME_DiffRemoveBackgroundColor = "org.eclipse.egit.ui.DiffRemoveBackgroundColor"; //$NON-NLS-1$
-	/** */
-	public final static String THEME_DiffRemoveForegroundColor = "org.eclipse.egit.ui.DiffRemoveForegroundColor"; //$NON-NLS-1$
-	/** */
-	public final static String DECORATOR_RECOMPUTE_ANCESTORS = "decorator_recompute_ancestors"; //$NON-NLS-1$
-	/** */
-	public final static String DECORATOR_FILETEXT_DECORATION = "decorator_filetext_decoration"; //$NON-NLS-1$
-	/** */
-	public final static String DECORATOR_FOLDERTEXT_DECORATION = "decorator_foldertext_decoration"; //$NON-NLS-1$
-	/** */
-	public final static String DECORATOR_PROJECTTEXT_DECORATION = "decorator_projecttext_decoration"; //$NON-NLS-1$
-	/** */
-	public final static String DECORATOR_SHOW_TRACKED_ICON = "decorator_show_tracked_icon"; //$NON-NLS-1$
-	/** */
-	public final static String DECORATOR_SHOW_UNTRACKED_ICON = "decorator_show_untracked_icon"; //$NON-NLS-1$
-	/** */
-	public final static String DECORATOR_SHOW_STAGED_ICON = "decorator_show_staged_icon"; //$NON-NLS-1$
-	/** */
-	public final static String DECORATOR_SHOW_CONFLICTS_ICON = "decorator_show_conflicts_icon"; //$NON-NLS-1$
-	/** */
-	public final static String DECORATOR_SHOW_ASSUME_VALID_ICON = "decorator_show_assume_valid_icon"; //$NON-NLS-1$
-	/** */
-	public final static String DECORATOR_SHOW_DIRTY_ICON = "decorator_show_dirty_icon"; //$NON-NLS-1$
-	/** */
-	public final static String SYNC_VIEW_CHANGESET_LABEL_FORMAT = "sync_view_changeset_pattern"; //$NON-NLS-1$
-	/** */
-	public final static String SYNC_VIEW_ALWAYS_SHOW_CHANGESET_MODEL = "sync_view_show_changeset_model"; //$NON-NLS-1$
-	/** */
-	public final static String SYNC_VIEW_LAST_SELECTED_MODEL = "sync_view_last_selected_model"; //$NON-NLS-1$
-	/** */
-	public static final String SYNC_VIEW_FETCH_BEFORE_LAUNCH = "sync_view_fetch_before_launch"; //$NON-NLS-1$
-	/** */
-	public final static String DATE_FORMAT = "date_format"; //$NON-NLS-1$
-	/** */
-	public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";  //$NON-NLS-1$
-	/** */
-	public static final String DEFAULT_CHANGESET_FORMAT = "[{author}] ({date}) {short_message}"; //$NON-NLS-1$
-	/** */
-	public static final String REFESH_ON_INDEX_CHANGE = "refesh_on_index_change"; //$NON-NLS-1$
-	/** */
-	public static final String REFESH_ONLY_WHEN_ACTIVE = "refesh_only_when_active"; //$NON-NLS-1$
-	/** */
-	public static final String REMOTE_CONNECTION_TIMEOUT = "remote_connection_timeout"; //$NON-NLS-1$
-	/** */
-	public static final String DEFAULT_REPO_DIR = "default_repository_dir"; //$NON-NLS-1$
-	/** */
-	public static final String MERGE_MODE = "merge_mode"; //$NON-NLS-1$
-	/** */
-	public static final String SHOW_REBASE_CONFIRM = "show_rebase_confirm"; //$NON-NLS-1$
-	/** */
-	public static final String SHOW_INITIAL_CONFIG_DIALOG = "show_initial_config_dialog"; //$NON-NLS-1$
-	/** */
-	public static final String SHOW_HOME_DIR_WARNING = "show_home_drive_warning"; //$NON-NLS-1$
-	/** */
-	public static final String SHOW_GIT_PREFIX_WARNING = "show_git_prefix_warning"; //$NON-NLS-1$
-	/** */
-	public static final String SHOW_DETACHED_HEAD_WARNING = "show_detached_head_warning"; //$NON-NLS-1$
-	/** */
-	public static final String TREE_COMPARE_SHOW_EQUALS = "CompareTreeView_ShowEquals"; //$NON-NLS-1$
-	/** */
-	public static final String HISTORY_MAX_NUM_COMMITS = "HistoryView_MaxNumberOfCommmits"; //$NON-NLS-1$
-	/** */
-	public static final String HISTORY_MAX_TAG_LENGTH = "HistoryView_MaxTagLength"; //$NON-NLS-1$
-	/** */
-	public static final String HISTORY_MAX_BRANCH_LENGTH = "HistoryView_MaxBranchLength"; //$NON-NLS-1$
-	/** */
-	public static final String HISTORY_SHOW_TAG_SEQUENCE = "HistoryView_ShowTagSequence"; //$NON-NLS-1$
-	/** */
-	public static final String STAGING_VIEW_SHOW_NEW_COMMITS = "StagingView_ShowNewCommits"; //$NON-NLS-1$
-	/** */
-	public static final String STAGING_VIEW_COLUMN_LAYOUT = "StagingView_ColumnLayout"; //$NON-NLS-1$
-	/** */
-	public static final String STAGING_VIEW_SYNC_SELECTION = "StagingView_SyncWithSelection"; //$NON-NLS-1$
-	/** */
-	public static final String STAGING_VIEW_FILENAME_MODE = "StagingView_FileNameMode"; //$NON-NLS-1$
-	/** */
-	public static final String PAGE_COMMIT_PREFERENCES = "org.eclipse.egit.ui.internal.preferences.CommitDialogPreferencePage"; //$NON-NLS-1$
-	/** */
-	public static final String BLAME_IGNORE_WHITESPACE = "Blame_IgnoreWhitespace"; //$NON-NLS-1$
-	/** */
-	public static final String CLONE_WIZARD_STORE_SECURESTORE = "CloneWizard_StoreInSecureStore"; //$NON-NLS-1$
-	/** */
-	public static final String CLONE_WIZARD_IMPORT_PROJECTS = "CloneWizard_ImportProjects"; //$NON-NLS-1$
-	/** */
-	public static final String CLONE_WIZARD_SHOW_DETAILED_FAILURE_DIALOG = "CloneWizard_ShowDetailedFailureDialog"; //$NON-NLS-1$
-
-	/**
-	 * Converts a persisted String separated with commas to an integer array
-	 *
-	 * @param value
-	 *            the String value
-	 * @param cnt
-	 *            number of entries in the returned array
-	 * @return the preference values for the array.
-	 */
-	public static int[] stringToIntArray(final String value, final int cnt) {
-		final int[] r = new int[cnt];
-		if (value != null) {
-			final String[] e = value.split(","); //$NON-NLS-1$
-			for (int i = 0; i < Math.min(e.length, r.length); i++)
-				r[i] = Integer.parseInt(e[i].trim());
-		}
-		return r;
-	}
-
-	/**
-	 * Converts an integer array into a String separated by commas
-	 *
-	 * @param data
-	 *            integers to store
-	 * @return the String
-	 */
-	public static String intArrayToString(final int[] data) {
-		final StringBuilder s = new StringBuilder();
-		for (int i = 0; i < data.length; i++) {
-			if (i > 0)
-				s.append(',');
-			s.append(data[i]);
-		}
-		return s.toString();
-	}
-}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIUtils.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIUtils.java
deleted file mode 100644
index 5321b14..0000000
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIUtils.java
+++ /dev/null
@@ -1,679 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010, 2012 SAP AG and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *    Mathias Kinzler (SAP AG) - initial implementation
- *******************************************************************************/
-package org.eclipse.egit.ui;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Pattern;
-import java.util.regex.PatternSyntaxException;
-
-import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.core.commands.NotEnabledException;
-import org.eclipse.core.commands.NotHandledException;
-import org.eclipse.core.commands.common.NotDefinedException;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.ui.internal.RepositorySaveableFilter;
-import org.eclipse.egit.ui.internal.UIIcons;
-import org.eclipse.egit.ui.internal.UIText;
-import org.eclipse.egit.ui.internal.components.RefContentProposal;
-import org.eclipse.jface.action.MenuManager;
-import org.eclipse.jface.bindings.keys.KeyStroke;
-import org.eclipse.jface.bindings.keys.ParseException;
-import org.eclipse.jface.dialogs.IDialogSettings;
-import org.eclipse.jface.fieldassist.ContentProposalAdapter;
-import org.eclipse.jface.fieldassist.ControlDecoration;
-import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
-import org.eclipse.jface.fieldassist.IContentProposal;
-import org.eclipse.jface.fieldassist.IContentProposalProvider;
-import org.eclipse.jface.fieldassist.TextContentAdapter;
-import org.eclipse.jface.resource.FontRegistry;
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.jface.resource.ResourceManager;
-import org.eclipse.jface.viewers.AbstractTreeViewer;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.jgit.lib.Ref;
-import org.eclipse.jgit.lib.Repository;
-import org.eclipse.osgi.util.NLS;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.DisposeEvent;
-import org.eclipse.swt.events.DisposeListener;
-import org.eclipse.swt.events.KeyEvent;
-import org.eclipse.swt.events.SelectionAdapter;
-import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Font;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.graphics.ImageData;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Resource;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Control;
-import org.eclipse.swt.widgets.Event;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.swt.widgets.ToolBar;
-import org.eclipse.swt.widgets.ToolItem;
-import org.eclipse.swt.widgets.Widget;
-import org.eclipse.ui.ISharedImages;
-import org.eclipse.ui.IWorkbench;
-import org.eclipse.ui.IWorkbenchCommandConstants;
-import org.eclipse.ui.IWorkbenchWindow;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.actions.ContributionItemFactory;
-import org.eclipse.ui.handlers.IHandlerService;
-import org.eclipse.ui.keys.IBindingService;
-
-/**
- * Some utilities for UI code
- */
-public class UIUtils {
-	/**
-	 * these activate the content assist; alphanumeric, space plus some expected
-	 * special chars
-	 */
-	private static final char[] VALUE_HELP_ACTIVATIONCHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123457890*@ <>".toCharArray(); //$NON-NLS-1$
-
-	/**
-	 * A keystroke for a "submit" action, see {@link #isSubmitKeyEvent(KeyEvent)}
-	 */
-	public static final KeyStroke SUBMIT_KEY_STROKE = KeyStroke.getInstance(SWT.MOD1, SWT.CR);
-
-	/**
-	 * Handles a "previously used values" content assist.
-	 * <p>
-	 * Adding this to a text field will enable "content assist" by keeping track
-	 * of the previously used valued for this field. The previously used values
-	 * will be shown in the order they were last used (most recently used ones
-	 * coming first in the list) and the number of entries is limited.
-	 * <p>
-	 * A "bulb" decorator will indicate that content assist is available for the
-	 * field, and a tool tip is provided giving more information.
-	 * <p>
-	 * Content assist is activated by either typing in the field or by using a
-	 * dedicated key stroke which is indicated in the tool tip. The list will be
-	 * filtered with the content already in the text field with '*' being usable
-	 * as wild card.
-	 * <p>
-	 * Note that the application must issue a call to {@link #updateProposals()}
-	 * in order to add a new value to the "previously used values" list.
-	 * <p>
-	 * The list will be persisted in the plug-in dialog settings.
-	 *
-	 * @noextend not to be extended by clients
-	 * @noimplement not to be implemented by clients, use
-	 *              {@link UIUtils#addPreviousValuesContentProposalToText(Text, String)}
-	 *              to create instances of this
-	 */
-	public interface IPreviousValueProposalHandler {
-		/**
-		 * Updates the proposal list from the value in the text field.
-		 * <p>
-		 * The value will be truncated to the first 2000 characters in order to
-		 * limit data size.
-		 * <p>
-		 * Note that this must be called in the UI thread, since it accesses the
-		 * text field.
-		 * <p>
-		 * If the value is already in the list, it will become the first entry,
-		 * otherwise it will be added at the beginning. Note that empty Strings
-		 * will not be stored. The length of the list is limited, and the
-		 * "oldest" entries will be removed once the limit is exceeded.
-		 * <p>
-		 * This call should only be issued if the value in the text field is
-		 * "valid" in terms of the application.
-		 */
-		public void updateProposals();
-	}
-
-	/**
-	 * Used for
-	 * {@link UIUtils#addRefContentProposalToText(Text, Repository, IRefListProvider)}
-	 */
-	public interface IRefListProvider {
-		/**
-		 * @return the List of {@link Ref}s to propose
-		 */
-		public List<Ref> getRefList();
-	}
-
-	/**
-	 * @param id
-	 *            see {@link FontRegistry#get(String)}
-	 * @return the font
-	 */
-	public static Font getFont(final String id) {
-		return PlatformUI.getWorkbench().getThemeManager().getCurrentTheme()
-				.getFontRegistry().get(id);
-	}
-
-	/**
-	 * @param id
-	 *            see {@link FontRegistry#getBold(String)}
-	 * @return the font
-	 */
-	public static Font getBoldFont(final String id) {
-		return PlatformUI.getWorkbench().getThemeManager().getCurrentTheme()
-				.getFontRegistry().getBold(id);
-	}
-
-	/**
-	 * @param id
-	 *            see {@link FontRegistry#getItalic(String)}
-	 * @return the font
-	 */
-	public static Font getItalicFont(final String id) {
-		return PlatformUI.getWorkbench().getThemeManager().getCurrentTheme()
-				.getFontRegistry().getItalic(id);
-	}
-
-	/**
-	 * Adds little bulb decoration to given control. Bulb will appear in top
-	 * left corner of control after giving focus for this control.
-	 *
-	 * After clicking on bulb image text from <code>tooltip</code> will appear.
-	 *
-	 * @param control
-	 *            instance of {@link Control} object with should be decorated
-	 * @param tooltip
-	 *            text value which should appear after clicking on bulb image.
-	 */
-	public static void addBulbDecorator(final Control control,
-			final String tooltip) {
-		ControlDecoration dec = new ControlDecoration(control, SWT.TOP
-				| SWT.LEFT);
-
-		dec.setImage(FieldDecorationRegistry.getDefault().getFieldDecoration(
-				FieldDecorationRegistry.DEC_CONTENT_PROPOSAL).getImage());
-
-		dec.setShowOnlyOnFocus(true);
-		dec.setShowHover(true);
-
-		dec.setDescriptionText(tooltip);
-	}
-
-	/**
-	 * Adds a "previously used values" content proposal handler to a text field.
-	 * <p>
-	 * The keyboard shortcut will be "M1+SPACE" and the list will be limited to
-	 * 10 values.
-	 *
-	 * @param textField
-	 *            the text field
-	 * @param preferenceKey
-	 *            the key under which to store the "previously used values" in
-	 *            the dialog settings
-	 * @return the handler the proposal handler
-	 */
-	public static IPreviousValueProposalHandler addPreviousValuesContentProposalToText(
-			final Text textField, final String preferenceKey) {
-		KeyStroke stroke;
-		try {
-			stroke = KeyStroke.getInstance("M1+SPACE"); //$NON-NLS-1$
-			addBulbDecorator(textField, NLS.bind(
-					UIText.UIUtils_PressShortcutMessage, stroke.format()));
-		} catch (ParseException e1) {
-			Activator.handleError(e1.getMessage(), e1, false);
-			stroke = null;
-			addBulbDecorator(textField,
-					UIText.UIUtils_StartTypingForPreviousValuesMessage);
-		}
-
-		IContentProposalProvider cp = new IContentProposalProvider() {
-
-			public IContentProposal[] getProposals(String contents, int position) {
-
-				List<IContentProposal> resultList = new ArrayList<IContentProposal>();
-
-				// make the simplest possible pattern check: allow "*"
-				// for multiple characters
-				String patternString = contents;
-				// ignore spaces in the beginning
-				while (patternString.length() > 0
-						&& patternString.charAt(0) == ' ') {
-					patternString = patternString.substring(1);
-				}
-
-				// we quote the string as it may contain spaces
-				// and other stuff colliding with the Pattern
-				patternString = Pattern.quote(patternString);
-
-				patternString = patternString.replaceAll("\\x2A", ".*"); //$NON-NLS-1$ //$NON-NLS-2$
-
-				// make sure we add a (logical) * at the end
-				if (!patternString.endsWith(".*")) { //$NON-NLS-1$
-					patternString = patternString + ".*"; //$NON-NLS-1$
-				}
-
-				// let's compile a case-insensitive pattern (assumes ASCII only)
-				Pattern pattern;
-				try {
-					pattern = Pattern.compile(patternString,
-							Pattern.CASE_INSENSITIVE);
-				} catch (PatternSyntaxException e) {
-					pattern = null;
-				}
-
-				String[] proposals = org.eclipse.egit.ui.Activator.getDefault()
-						.getDialogSettings().getArray(preferenceKey);
-
-				if (proposals != null)
-					for (final String uriString : proposals) {
-
-						if (pattern != null
-								&& !pattern.matcher(uriString).matches())
-							continue;
-
-						IContentProposal propsal = new IContentProposal() {
-
-							public String getLabel() {
-								return null;
-							}
-
-							public String getDescription() {
-								return null;
-							}
-
-							public int getCursorPosition() {
-								return 0;
-							}
-
-							public String getContent() {
-								return uriString;
-							}
-						};
-						resultList.add(propsal);
-					}
-
-				return resultList.toArray(new IContentProposal[resultList
-						.size()]);
-			}
-		};
-
-		ContentProposalAdapter adapter = new ContentProposalAdapter(textField,
-				new TextContentAdapter(), cp, stroke,
-				VALUE_HELP_ACTIVATIONCHARS);
-		// set the acceptance style to always replace the complete content
-		adapter
-				.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);
-
-		return new IPreviousValueProposalHandler() {
-			public void updateProposals() {
-				String value = textField.getText();
-				// don't store empty values
-				if (value.length() > 0) {
-					// we don't want to save too much in the preferences
-					if (value.length() > 2000) {
-						value = value.substring(0, 1999);
-					}
-					// now we need to mix the value into the list
-					IDialogSettings settings = org.eclipse.egit.ui.Activator
-							.getDefault().getDialogSettings();
-					String[] existingValues = settings.getArray(preferenceKey);
-					if (existingValues == null) {
-						existingValues = new String[] { value };
-						settings.put(preferenceKey, existingValues);
-					} else {
-
-						List<String> values = new ArrayList<String>(
-								existingValues.length + 1);
-
-						for (String existingValue : existingValues)
-							values.add(existingValue);
-						// if it is already the first value, we don't need to do
-						// anything
-						if (values.indexOf(value) == 0)
-							return;
-
-						values.remove(value);
-						// we insert at the top
-						values.add(0, value);
-						// make sure to not store more than the maximum number
-						// of values
-						while (values.size() > 10)
-							values.remove(values.size() - 1);
-
-						settings.put(preferenceKey, values
-								.toArray(new String[values.size()]));
-					}
-				}
-			}
-		};
-	}
-
-	/**
-	 * Adds a content proposal for {@link Ref}s (branches, tags...) to a text
-	 * field
-	 *
-	 * @param textField
-	 *            the text field
-	 * @param repository
-	 *            the repository
-	 * @param refListProvider
-	 *            provides the {@link Ref}s to show in the proposal
-	 */
-	public static final void addRefContentProposalToText(final Text textField,
-			final Repository repository, final IRefListProvider refListProvider) {
-		KeyStroke stroke;
-		try {
-			stroke = KeyStroke.getInstance("M1+SPACE"); //$NON-NLS-1$
-			UIUtils.addBulbDecorator(textField, NLS.bind(
-					UIText.UIUtils_PressShortcutMessage, stroke.format()));
-		} catch (ParseException e1) {
-			Activator.handleError(e1.getMessage(), e1, false);
-			stroke = null;
-			UIUtils.addBulbDecorator(textField,
-					UIText.UIUtils_StartTypingForPreviousValuesMessage);
-		}
-
-		IContentProposalProvider cp = new IContentProposalProvider() {
-			public IContentProposal[] getProposals(String contents, int position) {
-				List<IContentProposal> resultList = new ArrayList<IContentProposal>();
-
-				// make the simplest possible pattern check: allow "*"
-				// for multiple characters
-				String patternString = contents;
-				// ignore spaces in the beginning
-				while (patternString.length() > 0
-						&& patternString.charAt(0) == ' ') {
-					patternString = patternString.substring(1);
-				}
-
-				// we quote the string as it may contain spaces
-				// and other stuff colliding with the Pattern
-				patternString = Pattern.quote(patternString);
-
-				patternString = patternString.replaceAll("\\x2A", ".*"); //$NON-NLS-1$ //$NON-NLS-2$
-
-				// make sure we add a (logical) * at the end
-				if (!patternString.endsWith(".*")) { //$NON-NLS-1$
-					patternString = patternString + ".*"; //$NON-NLS-1$
-				}
-
-				// let's compile a case-insensitive pattern (assumes ASCII only)
-				Pattern pattern;
-				try {
-					pattern = Pattern.compile(patternString,
-							Pattern.CASE_INSENSITIVE);
-				} catch (PatternSyntaxException e) {
-					pattern = null;
-				}
-
-				List<Ref> proposals = refListProvider.getRefList();
-
-				if (proposals != null)
-					for (final Ref ref : proposals) {
-						final String shortenedName = Repository
-								.shortenRefName(ref.getName());
-						if (pattern != null
-								&& !pattern.matcher(ref.getName()).matches()
-								&& !pattern.matcher(shortenedName).matches())
-							continue;
-
-						IContentProposal propsal = new RefContentProposal(
-								repository, ref);
-						resultList.add(propsal);
-					}
-
-				return resultList.toArray(new IContentProposal[resultList
-						.size()]);
-			}
-		};
-
-		ContentProposalAdapter adapter = new ContentProposalAdapter(textField,
-				new TextContentAdapter(), cp, stroke,
-				UIUtils.VALUE_HELP_ACTIVATIONCHARS);
-		// set the acceptance style to always replace the complete content
-		adapter
-				.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);
-	}
-
-	/**
-	 * Set enabled state of the control and all its children
-	 * @param control
-	 * @param enable
-	 */
-	public static void setEnabledRecursively(final Control control,
-			final boolean enable) {
-		control.setEnabled(enable);
-		if (control instanceof Composite)
-			for (final Control child : ((Composite) control).getChildren())
-				setEnabledRecursively(child, enable);
-	}
-
-	/**
-	 * Dispose of the resource when the widget is disposed
-	 *
-	 * @param widget
-	 * @param resource
-	 */
-	public static void hookDisposal(Widget widget, final Resource resource) {
-		if (widget == null || resource == null)
-			return;
-
-		widget.addDisposeListener(new DisposeListener() {
-
-			public void widgetDisposed(DisposeEvent e) {
-				resource.dispose();
-			}
-		});
-	}
-
-	/**
-	 * Dispose of the resource manager when the widget is disposed
-	 *
-	 * @param widget
-	 * @param resources
-	 */
-	public static void hookDisposal(Widget widget,
-			final ResourceManager resources) {
-		if (widget == null || resources == null)
-			return;
-
-		widget.addDisposeListener(new DisposeListener() {
-
-			public void widgetDisposed(DisposeEvent e) {
-				resources.dispose();
-			}
-		});
-	}
-
-	/**
-	 * Get editor image for path
-	 *
-	 * @param path
-	 * @return image descriptor
-	 */
-	public static ImageDescriptor getEditorImage(final String path) {
-		if (path != null && path.length() > 0) {
-			final String name = new Path(path).lastSegment();
-			if (name != null)
-				return PlatformUI.getWorkbench().getEditorRegistry()
-						.getImageDescriptor(name);
-		}
-		return PlatformUI.getWorkbench().getSharedImages()
-				.getImageDescriptor(ISharedImages.IMG_OBJ_FILE);
-	}
-
-	/**
-	 * Get size of image descriptor as point.
-	 *
-	 * @param descriptor
-	 * @return size
-	 */
-	public static Point getSize(ImageDescriptor descriptor) {
-		ImageData data = descriptor.getImageData();
-		if (data == null)
-			return new Point(0, 0);
-		return new Point(data.width, data.height);
-	}
-
-	/**
-	 * Add expand all and collapse all toolbar items to the given toolbar bound
-	 * to the given tree viewer
-	 *
-	 * @param toolbar
-	 * @param viewer
-	 * @return given toolbar
-	 */
-	public static ToolBar addExpansionItems(final ToolBar toolbar,
-			final AbstractTreeViewer viewer) {
-		ToolItem collapseItem = new ToolItem(toolbar, SWT.PUSH);
-		Image collapseImage = UIIcons.COLLAPSEALL.createImage();
-		UIUtils.hookDisposal(collapseItem, collapseImage);
-		collapseItem.setImage(collapseImage);
-		collapseItem.setToolTipText(UIText.UIUtils_CollapseAll);
-		collapseItem.addSelectionListener(new SelectionAdapter() {
-
-			public void widgetSelected(SelectionEvent e) {
-				viewer.collapseAll();
-			}
-
-		});
-
-		ToolItem expandItem = new ToolItem(toolbar, SWT.PUSH);
-		Image expandImage = UIIcons.EXPAND_ALL.createImage();
-		UIUtils.hookDisposal(expandItem, expandImage);
-		expandItem.setImage(expandImage);
-		expandItem.setToolTipText(UIText.UIUtils_ExpandAll);
-		expandItem.addSelectionListener(new SelectionAdapter() {
-
-			public void widgetSelected(SelectionEvent e) {
-				viewer.expandAll();
-			}
-
-		});
-		return toolbar;
-	}
-
-	/**
-	 * Get dialog bound settings for given class using standard section name
-	 *
-	 * @param clazz
-	 * @return dialog setting
-	 */
-	public static IDialogSettings getDialogBoundSettings(final Class<?> clazz) {
-		return getDialogSettings(clazz.getName() + ".dialogBounds"); //$NON-NLS-1$
-	}
-
-	/**
-	 * Get dialog settings for given section name
-	 *
-	 * @param sectionName
-	 * @return dialog settings
-	 */
-	public static IDialogSettings getDialogSettings(final String sectionName) {
-		IDialogSettings settings = Activator.getDefault().getDialogSettings();
-		IDialogSettings section = settings.getSection(sectionName);
-		if (section == null)
-			section = settings.addNewSection(sectionName);
-		return section;
-	}
-
-	/**
-	 * Is viewer in a usable state?
-	 *
-	 * @param viewer
-	 * @return true if usable, false if null or underlying control is null or
-	 *         disposed
-	 */
-	public static boolean isUsable(final Viewer viewer) {
-		return viewer != null && isUsable(viewer.getControl());
-	}
-
-	/**
-	 * Is control usable?
-	 *
-	 * @param control
-	 * @return true if usable, false if null or disposed
-	 */
-	public static boolean isUsable(final Control control) {
-		return control != null && !control.isDisposed();
-	}
-
-	/**
-	 * Run command with specified id
-	 *
-	 * @param service
-	 * @param id
-	 */
-	public static void executeCommand(IHandlerService service, String id) {
-		executeCommand(service, id, null);
-	}
-
-	/**
-	 * Run command with specified id
-	 *
-	 * @param service
-	 * @param id
-	 * @param event
-	 */
-	public static void executeCommand(IHandlerService service, String id,
-			Event event) {
-		try {
-			service.executeCommand(id, event);
-		} catch (ExecutionException e) {
-			Activator.handleError(e.getMessage(), e, false);
-		} catch (NotDefinedException e) {
-			Activator.handleError(e.getMessage(), e, false);
-		} catch (NotEnabledException e) {
-			Activator.handleError(e.getMessage(), e, false);
-		} catch (NotHandledException e) {
-			Activator.handleError(e.getMessage(), e, false);
-		}
-	}
-
-	/**
-	 * Determine if the key event represents a "submit" action
-	 * (&lt;modifier&gt;+Enter).
-	 *
-	 * @param event
-	 * @return true, if it means submit, false otherwise
-	 */
-	public static boolean isSubmitKeyEvent(KeyEvent event) {
-		return (event.stateMask & SWT.MODIFIER_MASK) != 0
-				&& event.keyCode == SUBMIT_KEY_STROKE.getNaturalKey();
-	}
-
-	/**
-	 * Prompt for saving all dirty editors for resources in the working
-	 * directory of the specified repository.
-	 *
-	 * @param repository
-	 * @return true, if the user opted to continue, false otherwise
-	 * @see IWorkbench#saveAllEditors(boolean)
-	 */
-	public static boolean saveAllEditors(Repository repository) {
-		IWorkbench workbench = PlatformUI.getWorkbench();
-		IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
-		return workbench.saveAll(window, window, new RepositorySaveableFilter(repository), true);
-	}
-
-	/**
-	 * @param workbenchWindow the workbench window to use for creating the show in menu.
-	 * @return the show in menu
-	 */
-	public static MenuManager createShowInMenu(IWorkbenchWindow workbenchWindow) {
-		MenuManager showInSubMenu = new MenuManager(getShowInMenuLabel());
-		showInSubMenu.add(ContributionItemFactory.VIEWS_SHOW_IN.create(workbenchWindow));
-		return showInSubMenu;
-	}
-
-	private static String getShowInMenuLabel() {
-		IBindingService bindingService = (IBindingService) PlatformUI
-				.getWorkbench().getAdapter(IBindingService.class);
-		if (bindingService != null) {
-			String keyBinding = bindingService
-					.getBestActiveBindingFormattedFor(IWorkbenchCommandConstants.NAVIGATE_SHOW_IN_QUICK_MENU);
-			if (keyBinding != null)
-				return UIText.UIUtils_ShowInMenuLabel + '\t' + keyBinding;
-		}
-
-		return UIText.UIUtils_ShowInMenuLabel;
-	}
-}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/Activator.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/Activator.java
new file mode 100644
index 0000000..7f8e28e
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/Activator.java
@@ -0,0 +1,603 @@
+/*******************************************************************************
+ * Copyright (C) 2007,2010 Robin Rosenberg <robin.rosenberg@dewire.com>
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
+ * Copyright (C) 2010, Mathias Kinzler <mathias.kinzler@sap.com>
+ * Copyright (C) 2012, Matthias Sohn <matthias.sohn@sap.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal;
+
+import java.io.IOException;
+import java.net.Authenticator;
+import java.net.ProxySelector;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.eclipse.core.net.proxy.IProxyService;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.egit.core.internal.RepositoryUtil;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.egit.ui.internal.credentials.EGitCredentialsProvider;
+import org.eclipse.egit.ui.internal.trace.GitTraceLocation;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.jgit.events.IndexChangedEvent;
+import org.eclipse.jgit.events.IndexChangedListener;
+import org.eclipse.jgit.events.ListenerHandle;
+import org.eclipse.jgit.events.RepositoryEvent;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.transport.CredentialsProvider;
+import org.eclipse.jgit.transport.SshSessionFactory;
+import org.eclipse.jsch.core.IJSchService;
+import org.eclipse.osgi.service.debug.DebugOptions;
+import org.eclipse.osgi.service.debug.DebugOptionsListener;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IWindowListener;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.eclipse.ui.statushandlers.StatusManager;
+import org.eclipse.ui.themes.ITheme;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * This is a plugin singleton mostly controlling logging.
+ */
+public class Activator extends AbstractUIPlugin implements DebugOptionsListener {
+
+	/**
+	 *  The one and only instance
+	 */
+	private static Activator plugin;
+
+	/**
+	 * Property listeners for plugin specific events
+	 */
+	private static List<IPropertyChangeListener> propertyChangeListeners =
+		new ArrayList<IPropertyChangeListener>(5);
+
+	/**
+	 * Property constant indicating the decorator configuration has changed.
+	 */
+	public static final String DECORATORS_CHANGED = "org.eclipse.egit.ui.DECORATORS_CHANGED"; //$NON-NLS-1$
+
+	/**
+	 * @return the {@link Activator} singleton.
+	 */
+	public static Activator getDefault() {
+		return plugin;
+	}
+
+	/**
+	 * @return the id of the egit ui plugin
+	 */
+	public static String getPluginId() {
+		return getDefault().getBundle().getSymbolicName();
+	}
+
+	/**
+	 * Handle an error. The error is logged. If <code>show</code> is
+	 * <code>true</code> the error is shown to the user.
+	 *
+	 * @param message 		a localized message
+	 * @param throwable
+	 * @param show
+	 */
+	public static void handleError(String message, Throwable throwable,
+			boolean show) {
+		handleIssue(IStatus.ERROR, message, throwable, show);
+	}
+
+	/**
+	 * Handle an issue. The issue is logged. If <code>show</code> is
+	 * <code>true</code> the issue is shown to the user.
+	 *
+	 * @param severity
+	 *            status severity, use constants defined in {@link IStatus}
+	 * @param message
+	 *            a localized message
+	 * @param throwable
+	 * @param show
+	 * @since 2.2
+	 */
+	public static void handleIssue(int severity, String message, Throwable throwable,
+			boolean show) {
+		IStatus status = new Status(severity, getPluginId(), message,
+				throwable);
+		int style = StatusManager.LOG;
+		if (show)
+			style |= StatusManager.SHOW;
+		StatusManager.getManager().handle(status, style);
+	}
+
+	/**
+	 * Shows an error. The error is NOT logged.
+	 *
+	 * @param message
+	 *            a localized message
+	 * @param throwable
+	 */
+	public static void showError(String message, Throwable throwable) {
+		IStatus status = new Status(IStatus.ERROR, getPluginId(), message,
+				throwable);
+		StatusManager.getManager().handle(status, StatusManager.SHOW);
+	}
+
+	/**
+	 * Shows an error. The error is NOT logged.
+	 *
+	 * @param message
+	 *            a localized message
+	 * @param status
+	 */
+	public static void showErrorStatus(String message, IStatus status) {
+		StatusManager.getManager().handle(status, StatusManager.SHOW);
+	}
+
+	/**
+	 * Get the theme used by this plugin.
+	 *
+	 * @return our theme.
+	 */
+	public static ITheme getTheme() {
+		return plugin.getWorkbench().getThemeManager().getCurrentTheme();
+	}
+
+	/**
+	 * Get a font known to this plugin.
+	 *
+	 * @param id
+	 *            one of our THEME_* font preference ids (see
+	 *            {@link UIPreferences});
+	 * @return the configured font, borrowed from the registry.
+	 */
+	public static Font getFont(final String id) {
+		return getTheme().getFontRegistry().get(id);
+	}
+
+	/**
+	 * Get a font known to this plugin, but with bold style applied over top.
+	 *
+	 * @param id
+	 *            one of our THEME_* font preference ids (see
+	 *            {@link UIPreferences});
+	 * @return the configured font, borrowed from the registry.
+	 */
+	public static Font getBoldFont(final String id) {
+		return getTheme().getFontRegistry().getBold(id);
+	}
+
+	private RepositoryChangeScanner rcs;
+	private ResourceRefreshJob refreshJob;
+	private ListenerHandle refreshHandle;
+	private DebugOptions debugOptions;
+
+	private IWindowListener focusListener;
+
+	/**
+	 * Construct the {@link Activator} egit ui plugin singleton instance
+	 */
+	public Activator() {
+		Activator.setActivator(this);
+	}
+
+	private static void setActivator(Activator a) {
+		plugin = a;
+	}
+
+
+	public void start(final BundleContext context) throws Exception {
+		super.start(context);
+
+		// we want to be notified about debug options changes
+		Dictionary<String, String> props = new Hashtable<String, String>(4);
+		props.put(DebugOptions.LISTENER_SYMBOLICNAME, context.getBundle()
+				.getSymbolicName());
+		context.registerService(DebugOptionsListener.class.getName(), this,
+				props);
+
+		setupSSH(context);
+		setupProxy(context);
+		setupRepoChangeScanner();
+		setupRepoIndexRefresh();
+		setupFocusHandling();
+		setupCredentialsProvider();
+		ConfigurationChecker.checkConfiguration();
+	}
+
+	private void setupCredentialsProvider() {
+		CredentialsProvider.setDefault(new EGitCredentialsProvider());
+	}
+
+	static boolean isActive() {
+		final AtomicBoolean ret = new AtomicBoolean();
+		final Display display = PlatformUI.getWorkbench().getDisplay();
+		if (display.isDisposed())
+			return false;
+		display.syncExec(new Runnable() {
+			public void run() {
+				ret.set(display.getActiveShell() != null);
+			}
+		});
+		return ret.get();
+	}
+
+	private void setupFocusHandling() {
+		focusListener = new IWindowListener() {
+
+			public void windowOpened(IWorkbenchWindow window) {
+				// nothing
+			}
+
+			public void windowDeactivated(IWorkbenchWindow window) {
+				// nothing
+			}
+
+			public void windowClosed(IWorkbenchWindow window) {
+				// nothing
+			}
+
+			public void windowActivated(IWorkbenchWindow window) {
+				if (rcs.doReschedule)
+					rcs.schedule();
+				refreshJob.triggerRefresh();
+			}
+		};
+		PlatformUI.getWorkbench().addWindowListener(focusListener);
+	}
+
+	public void optionsChanged(DebugOptions options) {
+		// initialize the trace stuff
+		debugOptions = options;
+		GitTraceLocation.initializeFromOptions(options, isDebugging());
+	}
+
+	/**
+	 * @return the {@link DebugOptions}
+	 */
+	public DebugOptions getDebugOptions() {
+		return debugOptions;
+	}
+
+	private void setupRepoIndexRefresh() {
+		refreshJob = new ResourceRefreshJob();
+		refreshHandle = Repository.getGlobalListenerList()
+				.addIndexChangedListener(refreshJob);
+	}
+
+	/**
+	 * Register for changes made to Team properties.
+	 *
+	 * @param listener
+	 *            The listener to register
+	 */
+	public static synchronized void addPropertyChangeListener(
+			IPropertyChangeListener listener) {
+		propertyChangeListeners.add(listener);
+	}
+
+	/**
+	 * Remove a Team property changes.
+	 *
+	 * @param listener
+	 *            The listener to remove
+	 */
+	public static synchronized void removePropertyChangeListener(
+			IPropertyChangeListener listener) {
+		propertyChangeListeners.remove(listener);
+	}
+
+	/**
+	 * Broadcast a Team property change.
+	 *
+	 * @param event
+	 *            The event to broadcast
+	 */
+	public static synchronized void broadcastPropertyChange(PropertyChangeEvent event) {
+		for (IPropertyChangeListener listener : propertyChangeListeners)
+			listener.propertyChange(event);
+	}
+
+	/**
+	 * Refresh projects in repositories that we suspect may have resource
+	 * changes.
+	 */
+	static class ResourceRefreshJob extends Job implements IndexChangedListener {
+
+		ResourceRefreshJob() {
+			super(UIText.Activator_refreshJobName);
+		}
+
+		private Set<IProject> projectsToScan = new LinkedHashSet<IProject>();
+		private Set<Repository> repositoriesChanged = new HashSet<Repository>();
+
+		@Override
+		protected IStatus run(IProgressMonitor monitor) {
+			IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
+			monitor.beginTask(UIText.Activator_refreshingProjects, projects.length);
+
+			while (projectsToScan.size() > 0) {
+				IProject p;
+				synchronized (projectsToScan) {
+					if (projectsToScan.size() == 0)
+						break;
+					Iterator<IProject> i = projectsToScan.iterator();
+					p = i.next();
+					i.remove();
+				}
+				ISchedulingRule rule = p.getWorkspace().getRuleFactory().refreshRule(p);
+				try {
+					getJobManager().beginRule(rule, monitor);
+					if(p.exists()) // handle missing projects after branch switch
+						p.refreshLocal(IResource.DEPTH_INFINITE, new SubProgressMonitor(monitor, 1));
+				} catch (CoreException e) {
+					handleError(UIText.Activator_refreshFailed, e, false);
+					return new Status(IStatus.ERROR, getPluginId(), e.getMessage());
+				} finally {
+					getJobManager().endRule(rule);
+				}
+			}
+			monitor.done();
+			return Status.OK_STATUS;
+		}
+
+		public void onIndexChanged(IndexChangedEvent e) {
+			if (Activator.getDefault().getPreferenceStore()
+					.getBoolean(UIPreferences.REFESH_ON_INDEX_CHANGE))
+				mayTriggerRefresh(e);
+		}
+
+		/**
+		 * Record which projects have changes. Initiate a resource refresh job
+		 * if the user settings allow it.
+		 *
+		 * @param e
+		 *            The {@link RepositoryEvent} that triggered this refresh
+		 */
+		private void mayTriggerRefresh(RepositoryEvent e) {
+			repositoriesChanged.add(e.getRepository());
+			if (!Activator.getDefault().getPreferenceStore()
+					.getBoolean(UIPreferences.REFESH_ONLY_WHEN_ACTIVE)
+					|| isActive())
+				triggerRefresh();
+		}
+
+		/**
+		 * Figure which projects belong to a repository, add them to a set of
+		 * project to refresh and schedule the refresh as a job.
+		 */
+		void triggerRefresh() {
+			if (GitTraceLocation.REPOSITORYCHANGESCANNER.isActive())
+				GitTraceLocation.getTrace().trace(
+						GitTraceLocation.REPOSITORYCHANGESCANNER.getLocation(),
+						"Triggered refresh"); //$NON-NLS-1$
+			IProject[] projects = ResourcesPlugin.getWorkspace().getRoot()
+					.getProjects();
+			Set<IProject> toRefresh = new HashSet<IProject>();
+			synchronized (repositoriesChanged) {
+				for (IProject p : projects) {
+					RepositoryMapping mapping = RepositoryMapping.getMapping(p);
+					if (mapping != null
+							&& repositoriesChanged.contains(mapping
+									.getRepository())) {
+						toRefresh.add(p);
+					}
+				}
+				repositoriesChanged.clear();
+			}
+			synchronized (projectsToScan) {
+				projectsToScan.addAll(toRefresh);
+			}
+			if (projectsToScan.size() > 0)
+				schedule();
+		}
+	}
+
+	/**
+	 * A Job that looks at the repository meta data and triggers a refresh of
+	 * the resources in the affected projects.
+	 */
+	static class RepositoryChangeScanner extends Job {
+		RepositoryChangeScanner() {
+			super(UIText.Activator_repoScanJobName);
+		}
+
+		// FIXME, need to be more intelligent about this to avoid too much work
+		private static final long REPO_SCAN_INTERVAL = 10000L;
+		// volatile in order to ensure thread synchronization
+		private volatile boolean doReschedule = true;
+
+		void setReschedule(boolean reschedule){
+			doReschedule = reschedule;
+		}
+
+		@Override
+		protected IStatus run(IProgressMonitor monitor) {
+			Repository[] repos = org.eclipse.egit.core.internal.Activator.getDefault()
+					.getRepositoryCache().getAllRepositories();
+			if (repos.length == 0)
+				return Status.OK_STATUS;
+
+			// When people use Git from the command line a lot of changes
+			// may happen. Don't scan when inactive depending on the user's
+			// choice.
+
+			if (Activator.getDefault().getPreferenceStore()
+					.getBoolean(UIPreferences.REFESH_ONLY_WHEN_ACTIVE)) {
+				if (!isActive()) {
+					monitor.done();
+					if (doReschedule)
+						schedule(REPO_SCAN_INTERVAL);
+					return Status.OK_STATUS;
+				}
+			}
+
+			monitor.beginTask(UIText.Activator_scanningRepositories,
+					repos.length);
+			try {
+				for (Repository repo : repos) {
+					if (monitor.isCanceled())
+						break;
+					if (GitTraceLocation.REPOSITORYCHANGESCANNER.isActive())
+						GitTraceLocation.getTrace().trace(
+								GitTraceLocation.REPOSITORYCHANGESCANNER
+										.getLocation(),
+								"Scanning " + repo + " for changes"); //$NON-NLS-1$ //$NON-NLS-2$
+
+					repo.scanForRepoChanges();
+					monitor.worked(1);
+				}
+			} catch (IOException e) {
+				if (GitTraceLocation.REPOSITORYCHANGESCANNER.isActive())
+					GitTraceLocation.getTrace().trace(
+							GitTraceLocation.REPOSITORYCHANGESCANNER
+									.getLocation(),
+							"Stopped rescheduling " + getName() + "job"); //$NON-NLS-1$ //$NON-NLS-2$
+				return createErrorStatus(UIText.Activator_scanError, e);
+			} finally {
+				monitor.done();
+			}
+			if (GitTraceLocation.REPOSITORYCHANGESCANNER.isActive())
+				GitTraceLocation.getTrace().trace(
+						GitTraceLocation.REPOSITORYCHANGESCANNER.getLocation(),
+						"Rescheduling " + getName() + " job"); //$NON-NLS-1$ //$NON-NLS-2$
+			if (doReschedule)
+				schedule(REPO_SCAN_INTERVAL);
+			return Status.OK_STATUS;
+		}
+	}
+
+	private void setupRepoChangeScanner() {
+		rcs = new RepositoryChangeScanner();
+		rcs.setSystem(true);
+		rcs.schedule(RepositoryChangeScanner.REPO_SCAN_INTERVAL);
+	}
+
+	private void setupSSH(final BundleContext context) {
+		final ServiceReference ssh;
+
+		ssh = context.getServiceReference(IJSchService.class.getName());
+		if (ssh != null) {
+			SshSessionFactory.setInstance(new EclipseSshSessionFactory(
+					(IJSchService) context.getService(ssh)));
+		}
+	}
+
+	private void setupProxy(final BundleContext context) {
+		final ServiceReference proxy;
+
+		proxy = context.getServiceReference(IProxyService.class.getName());
+		if (proxy != null) {
+			ProxySelector.setDefault(new EclipseProxySelector(
+					(IProxyService) context.getService(proxy)));
+			Authenticator.setDefault(new EclipseAuthenticator(
+					(IProxyService) context.getService(proxy)));
+		}
+	}
+
+	public void stop(final BundleContext context) throws Exception {
+		if (refreshHandle != null) {
+			refreshHandle.remove();
+			refreshHandle = null;
+		}
+
+		if (focusListener != null) {
+			PlatformUI.getWorkbench().removeWindowListener(focusListener);
+			focusListener = null;
+		}
+
+		if (GitTraceLocation.REPOSITORYCHANGESCANNER.isActive())
+			GitTraceLocation.getTrace().trace(
+					GitTraceLocation.REPOSITORYCHANGESCANNER.getLocation(),
+					"Trying to cancel " + rcs.getName() + " job"); //$NON-NLS-1$ //$NON-NLS-2$
+
+		rcs.setReschedule(false);
+
+		rcs.cancel();
+		if (GitTraceLocation.REPOSITORYCHANGESCANNER.isActive())
+			GitTraceLocation.getTrace().trace(
+					GitTraceLocation.REPOSITORYCHANGESCANNER.getLocation(),
+					"Trying to cancel " + refreshJob.getName() + " job"); //$NON-NLS-1$ //$NON-NLS-2$
+		refreshJob.cancel();
+
+		rcs.join();
+		refreshJob.join();
+
+		if (GitTraceLocation.REPOSITORYCHANGESCANNER.isActive())
+			GitTraceLocation.getTrace().trace(
+					GitTraceLocation.REPOSITORYCHANGESCANNER.getLocation(),
+					"Jobs terminated"); //$NON-NLS-1$
+
+		super.stop(context);
+		plugin = null;
+	}
+
+	/**
+	 * @param message
+	 * @param e
+	 */
+	public static void logError(String message, Throwable e) {
+		handleError(message, e, false);
+	}
+
+	/**
+	 * @param message
+	 * @param e
+	 */
+	public static void error(String message, Throwable e) {
+		handleError(message, e, false);
+	}
+
+	/**
+	 * Creates an error status
+	 *
+	 * @param message
+	 *            a localized message
+	 * @param throwable
+	 * @return a new Status object
+	 */
+	public static IStatus createErrorStatus(String message, Throwable throwable) {
+		return new Status(IStatus.ERROR, getPluginId(), message, throwable);
+	}
+
+	/**
+	 * Creates an error status
+	 *
+	 * @param message
+	 *            a localized message
+	 * @return a new Status object
+	 */
+	public static IStatus createErrorStatus(String message) {
+		return new Status(IStatus.ERROR, getPluginId(), message);
+	}
+
+	/**
+	 * @return the {@link RepositoryUtil} instance
+	 */
+	public RepositoryUtil getRepositoryUtil() {
+		return org.eclipse.egit.core.internal.Activator.getDefault().getRepositoryUtil();
+	}
+
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/CompareUtils.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/CompareUtils.java
index 425aa0a..01222b3 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/CompareUtils.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/CompareUtils.java
@@ -45,14 +45,13 @@
 import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener;
 import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;
 import org.eclipse.core.runtime.preferences.InstanceScope;
-import org.eclipse.egit.core.RevUtils;
 import org.eclipse.egit.core.internal.CompareCoreUtils;
+import org.eclipse.egit.core.internal.RevUtils;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
 import org.eclipse.egit.core.internal.storage.GitFileRevision;
 import org.eclipse.egit.core.internal.storage.WorkingTreeFileRevision;
 import org.eclipse.egit.core.internal.storage.WorkspaceFileRevision;
 import org.eclipse.egit.core.internal.util.ResourceUtil;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.ui.Activator;
 import org.eclipse.egit.ui.internal.GitCompareFileRevisionEditorInput.EmptyTypedElement;
 import org.eclipse.egit.ui.internal.actions.CompareWithCommitActionHandler;
 import org.eclipse.egit.ui.internal.merge.GitCompareEditorInput;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/ConfigurationChecker.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/ConfigurationChecker.java
index 59289db..8cf161e 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/ConfigurationChecker.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/ConfigurationChecker.java
@@ -15,8 +15,6 @@
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.jgit.util.FS;
 import org.eclipse.jgit.util.SystemReader;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/DecorationOverlayDescriptor.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/DecorationOverlayDescriptor.java
index cbd1956..6574dd0 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/DecorationOverlayDescriptor.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/DecorationOverlayDescriptor.java
@@ -12,7 +12,6 @@
 
 import java.util.Arrays;
 
-import org.eclipse.egit.ui.UIUtils;
 import org.eclipse.jface.resource.CompositeImageDescriptor;
 import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.jface.viewers.DecorationOverlayIcon;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/EclipseAuthenticator.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/EclipseAuthenticator.java
new file mode 100644
index 0000000..1f05a78
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/EclipseAuthenticator.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal;
+
+import java.net.Authenticator;
+import java.net.InetAddress;
+import java.net.PasswordAuthentication;
+import java.net.UnknownHostException;
+
+import org.eclipse.core.net.proxy.IProxyData;
+import org.eclipse.core.net.proxy.IProxyService;
+
+class EclipseAuthenticator extends Authenticator {
+	private final IProxyService service;
+
+	EclipseAuthenticator(final IProxyService s) {
+		service = s;
+	}
+
+	@Override
+	protected PasswordAuthentication getPasswordAuthentication() {
+		final IProxyData[] data = service.getProxyData();
+		if (data == null)
+			return null;
+		for (final IProxyData d : data) {
+			if (d.getUserId() == null || d.getHost() == null)
+				continue;
+			if (d.getPort() == getRequestingPort() && hostMatches(d))
+				return auth(d);
+		}
+		return null;
+	}
+
+	private PasswordAuthentication auth(final IProxyData d) {
+		final String user = d.getUserId();
+		final String pass = d.getPassword();
+		final char[] passChar = pass != null ? pass.toCharArray() : new char[0];
+		return new PasswordAuthentication(user, passChar);
+	}
+
+	private boolean hostMatches(final IProxyData d) {
+		try {
+			final InetAddress dHost = InetAddress.getByName(d.getHost());
+			InetAddress rHost = getRequestingSite();
+			if (rHost == null)
+				rHost = InetAddress.getByName(getRequestingHost());
+			return dHost.equals(rHost);
+		} catch (UnknownHostException err) {
+			return false;
+		}
+	}
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/EclipseProxySelector.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/EclipseProxySelector.java
new file mode 100644
index 0000000..e800635
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/EclipseProxySelector.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Proxy;
+import java.net.ProxySelector;
+import java.net.SocketAddress;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.net.proxy.IProxyData;
+import org.eclipse.core.net.proxy.IProxyService;
+
+class EclipseProxySelector extends ProxySelector {
+	private final IProxyService service;
+
+	EclipseProxySelector(final IProxyService s) {
+		service = s;
+	}
+
+	@Override
+	public List<Proxy> select(final URI uri) {
+		final ArrayList<Proxy> r = new ArrayList<Proxy>();
+		final String host = uri.getHost();
+
+		if (host != null) {
+			String type = IProxyData.SOCKS_PROXY_TYPE;
+			if ("http".equals(uri.getScheme())) //$NON-NLS-1$
+				type = IProxyData.HTTP_PROXY_TYPE;
+			else if ("ftp".equals(uri.getScheme())) //$NON-NLS-1$
+				type = IProxyData.HTTP_PROXY_TYPE;
+			else if ("https".equals(uri.getScheme())) //$NON-NLS-1$
+				type = IProxyData.HTTPS_PROXY_TYPE;
+			try {
+				URI queryUri = new URI(type, "//" + host, null); //$NON-NLS-1$
+				final IProxyData[] dataArray = service.select(queryUri);
+				for (IProxyData data : dataArray) {
+					if (IProxyData.HTTP_PROXY_TYPE.equals(data.getType()))
+						addProxy(r, Proxy.Type.HTTP, data);
+					else if (IProxyData.HTTPS_PROXY_TYPE.equals(data.getType()))
+						addProxy(r, Proxy.Type.HTTP, data);
+					else if (IProxyData.SOCKS_PROXY_TYPE.equals(data.getType()))
+						addProxy(r, Proxy.Type.SOCKS, data);
+				}
+			} catch (URISyntaxException e) {
+				// just add nothing to r
+			}
+		}
+		if (r.isEmpty())
+			r.add(Proxy.NO_PROXY);
+		return r;
+	}
+
+	private void addProxy(final ArrayList<Proxy> r, final Proxy.Type type,
+			final IProxyData d) {
+		try {
+			r.add(new Proxy(type, new InetSocketAddress(InetAddress.getByName(d
+					.getHost()), d.getPort())));
+		} catch (UnknownHostException uhe) {
+			// Oh well.
+		}
+	}
+
+	@Override
+	public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
+		// Don't tell Eclipse.
+	}
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/EclipseSshSessionFactory.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/EclipseSshSessionFactory.java
new file mode 100644
index 0000000..bbefbf4
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/EclipseSshSessionFactory.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
+ * Copyright (C) 2009, Google, Inc.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal;
+
+import org.eclipse.jgit.transport.JschConfigSessionFactory;
+import org.eclipse.jgit.transport.OpenSshConfig;
+import org.eclipse.jgit.util.FS;
+import org.eclipse.jsch.core.IJSchService;
+import org.eclipse.jsch.ui.UserInfoPrompter;
+
+import com.jcraft.jsch.JSch;
+import com.jcraft.jsch.JSchException;
+import com.jcraft.jsch.Session;
+import com.jcraft.jsch.UserInfo;
+
+class EclipseSshSessionFactory extends JschConfigSessionFactory {
+	private final IJSchService provider;
+
+	EclipseSshSessionFactory(final IJSchService p) {
+		provider = p;
+	}
+
+	@Override
+	protected JSch createDefaultJSch(FS fs) throws JSchException {
+		// Forcing a dummy session to be created will cause the known hosts
+		// and configured private keys to be initialized. This is needed by
+		// our parent class in case non-default JSch instances need to be made.
+		//
+		provider.createSession("127.0.0.1", 0, "eclipse"); //$NON-NLS-1$ //$NON-NLS-2$
+		return provider.getJSch();
+	}
+
+	@Override
+	protected Session createSession(final OpenSshConfig.Host hc,
+			final String user, final String host, final int port, FS fs)
+			throws JSchException {
+		final JSch jsch = getJSch(hc, FS.DETECTED);
+		if (jsch == provider.getJSch()) {
+			// If its the default JSch desired, let the provider
+			// manage the session creation for us.
+			//
+			return provider.createSession(host, port, user);
+		} else {
+			// This host configuration is using a different IdentityFile,
+			// one that is not available through the default JSch.
+			//
+			return jsch.getSession(user, host, port);
+		}
+	}
+
+	@Override
+	protected void configure(final OpenSshConfig.Host hc, final Session session) {
+		UserInfo userInfo = session.getUserInfo();
+		if (!hc.isBatchMode() && userInfo == null)
+			new UserInfoPrompter(session);
+	}
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/EgitUiEditorUtils.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/EgitUiEditorUtils.java
index ceb7ef3..7d9065d 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/EgitUiEditorUtils.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/EgitUiEditorUtils.java
@@ -24,7 +24,6 @@
 import org.eclipse.core.runtime.Platform;
 import org.eclipse.core.runtime.content.IContentType;
 import org.eclipse.egit.core.internal.util.ResourceUtil;
-import org.eclipse.egit.ui.Activator;
 import org.eclipse.jface.util.OpenStrategy;
 import org.eclipse.osgi.util.NLS;
 import org.eclipse.team.core.history.IFileRevision;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/FileEditableRevision.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/FileEditableRevision.java
index 4d00da9..1a7250e 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/FileEditableRevision.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/FileEditableRevision.java
@@ -16,7 +16,6 @@
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.egit.core.internal.CompareCoreUtils;
-import org.eclipse.egit.ui.Activator;
 import org.eclipse.jface.operation.IRunnableContext;
 import org.eclipse.jface.operation.IRunnableWithProgress;
 import org.eclipse.team.core.history.IFileRevision;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/GitCompareFileRevisionEditorInput.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/GitCompareFileRevisionEditorInput.java
index 3c0646a..a3bc7df 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/GitCompareFileRevisionEditorInput.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/GitCompareFileRevisionEditorInput.java
@@ -30,7 +30,7 @@
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.egit.core.Activator;
+import org.eclipse.egit.core.internal.Activator;
 import org.eclipse.osgi.util.NLS;
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.team.internal.ui.Utils;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/GitLabelProvider.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/GitLabelProvider.java
index dacc5cd..86037c6 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/GitLabelProvider.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/GitLabelProvider.java
@@ -15,7 +15,6 @@
 
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.egit.ui.Activator;
 import org.eclipse.egit.ui.internal.clone.ProjectRecord;
 import org.eclipse.egit.ui.internal.commit.RepositoryCommit;
 import org.eclipse.egit.ui.internal.repository.tree.RefNode;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/GitRepositoriesPerspectiveFactory.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/GitRepositoriesPerspectiveFactory.java
new file mode 100644
index 0000000..a38ec5c
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/GitRepositoriesPerspectiveFactory.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2011 SAP AG and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Mathias Kinzler (SAP AG) - initial implementation
+ *    Daniel Megert <daniel_megert@ch.ibm.com> - EGit must not pollute toolbars of perspectives it doesn't own - http://bugs.eclipse.org/356554
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal;
+
+import org.eclipse.egit.ui.internal.reflog.ReflogView;
+import org.eclipse.egit.ui.internal.repository.RepositoriesView;
+import org.eclipse.egit.ui.internal.staging.StagingView;
+import org.eclipse.team.ui.history.IHistoryView;
+import org.eclipse.team.ui.synchronize.ISynchronizeView;
+import org.eclipse.ui.IFolderLayout;
+import org.eclipse.ui.IPageLayout;
+import org.eclipse.ui.IPerspectiveFactory;
+
+/**
+ * Git Repository Exploring perspective factory
+ */
+public class GitRepositoriesPerspectiveFactory implements IPerspectiveFactory {
+
+	public void createInitialLayout(IPageLayout layout) {
+
+		// repositories on the left hand
+		layout.addView(RepositoriesView.VIEW_ID, IPageLayout.LEFT, (float) 0.5, layout.getEditorArea());
+
+		IFolderLayout bottom = layout.createFolder(
+				"bottom", IPageLayout.BOTTOM, (float) 0.5, //$NON-NLS-1$
+				layout.getEditorArea());
+
+		// Views under editor area
+		bottom.addView(IPageLayout.ID_PROP_SHEET);
+		bottom.addView(IHistoryView.VIEW_ID);
+		bottom.addView(ISynchronizeView.VIEW_ID);
+		bottom.addView(StagingView.VIEW_ID);
+		bottom.addView(ReflogView.VIEW_ID);
+
+		// place holder for Package Explorer under repositories
+		layout.addPlaceholder("org.eclipse.jdt.ui.PackageExplorer", IPageLayout.BOTTOM, (float) 0.7, RepositoriesView.VIEW_ID); //$NON-NLS-1$
+
+		// shortcut to Package Explorer
+		layout.addShowViewShortcut("org.eclipse.jdt.ui.PackageExplorer"); //$NON-NLS-1$
+		// shortcut to History view
+		layout.addShowViewShortcut(IHistoryView.VIEW_ID);
+		// shortcut to Synchronize view
+		layout.addShowViewShortcut(ISynchronizeView.VIEW_ID);
+		// shortcut to Staging view
+		layout.addShowViewShortcut(StagingView.VIEW_ID);
+		// shortcut to Reflog view
+		layout.addShowViewShortcut(ReflogView.VIEW_ID);
+
+		layout.addActionSet("org.eclipse.egit.ui.navigation"); //$NON-NLS-1$
+	}
+
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/JobFamilies.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/JobFamilies.java
new file mode 100644
index 0000000..a876793
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/JobFamilies.java
@@ -0,0 +1,156 @@
+/*******************************************************************************
+ * Copyright (C) 2010, Jens Baumgart <jens.baumgart@sap.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal;
+
+/**
+ * Job families of EGit jobs. May be used in tests to join job execution.
+ *
+ */
+public class JobFamilies {
+	/**
+	 * GenerateHistoryJob
+	 */
+	public final static Object GENERATE_HISTORY = new Object();
+
+	/**
+	 * Commit job
+	 */
+	public final static Object COMMIT = new Object();
+
+	/**
+	 * Checkout job
+	 */
+	public final static Object CHECKOUT = new Object();
+
+	/**
+	 * Push job
+	 */
+	public final static Object PUSH = new Object();
+
+	/**
+	 * Fetch job
+	 */
+	public final static Object FETCH = new Object();
+
+	/**
+	 * Repositories View refresh
+	 */
+	public final static Object REPO_VIEW_REFRESH = new Object();
+
+	/**
+	 * Delete repository job
+	 */
+	public final static Object REPOSITORY_DELETE = new Object();
+
+	/**
+	 * Tag job
+	 */
+	public final static Object TAG = new Object();
+
+	/**
+	 * Reset job
+	 */
+	public static final Object RESET = new Object();
+
+	/**
+	 * Rebase job
+	 */
+	public static final Object REBASE = new Object();
+
+	/**
+	 * Pull job
+	 */
+	public final static Object PULL = new Object();
+
+	/**
+	 * Format job
+	 */
+	public final static Object FORMAT_COMMIT_INFO = new Object();
+
+	/**
+	 * Fill tag list
+	 */
+	public final static Object FILL_TAG_LIST = new Object();
+
+	/**
+	 * AssumeUnchanged/NoAssumeUnchanged
+	 */
+	public final static Object ASSUME_NOASSUME_UNCHANGED = new Object();
+
+	/**
+	 * Untrack
+	 */
+	public final static Object UNTRACK = new Object();
+
+	/**
+	 * Disconnect
+	 */
+	public final static Object DISCONNECT = new Object();
+
+	/**
+	 * Discard Changes
+	 */
+	public final static Object DISCARD_CHANGES = new Object();
+
+
+	/**
+	 * Add to index job
+	 */
+	public static final Object ADD_TO_INDEX = new Object();
+
+	/**
+	 * Remove from index job
+	 */
+	public static final Object REMOVE_FROM_INDEX = new Object();
+
+	/**
+	 * Cherry pick commit job
+	 */
+	public static final Object CHERRY_PICK = new Object();
+
+	/**
+	 * Revert commit job
+	 */
+	public static final Object REVERT_COMMIT = new Object();
+
+	/**
+	 * Clone repository job
+	 */
+	public static final Object CLONE = new Object();
+
+	/**
+	 * Fetch data from git job
+	 */
+	public static final Object SYNCHRONIZE_READ_DATA = new Object();
+
+	/**
+	 * Show annotations git job
+	 */
+	public static final Object BLAME = new Object();
+
+	/**
+	 * Submodule add git job
+	 */
+	public static final Object SUBMODULE_ADD = new Object();
+
+	/**
+	 * Submodule sync git job
+	 */
+	public static final Object SUBMODULE_SYNC = new Object();
+
+	/**
+	 * Submodule update git job
+	 */
+	public static final Object SUBMODULE_UPDATE = new Object();
+
+	/**
+	 * Stash git job
+	 */
+	public static final Object STASH = new Object();
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/PluginPreferenceInitializer.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/PluginPreferenceInitializer.java
new file mode 100644
index 0000000..71f0754
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/PluginPreferenceInitializer.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (C) 2008, Roger C. Soares <rogersoares@intelinet.com.br>
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
+ * Copyright (C) 2010, Mathias Kinzler <mathias.kinzler@sap.com>
+ * Copyright (C) 2012, Daniel Megert <daniel_megert@ch.ibm.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal;
+
+import java.io.File;
+
+import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
+import org.eclipse.egit.ui.internal.decorators.GitLightweightDecorator;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jgit.util.FS;
+
+/**
+ * Plugin extension point to initialize the plugin runtime preferences.
+ */
+public class PluginPreferenceInitializer extends AbstractPreferenceInitializer {
+
+	/**
+	 * Calls super constructor.
+	 */
+	public PluginPreferenceInitializer() {
+		super();
+	}
+
+	/**
+	 * This method initializes the plugin preferences with default values.
+	 */
+	public void initializeDefaultPreferences() {
+		IPreferenceStore store = Activator.getDefault().getPreferenceStore();
+		int[] w;
+
+		store.setDefault(UIPreferences.RESOURCEHISTORY_SHOW_RELATIVE_DATE, true);
+		store.setDefault(UIPreferences.RESOURCEHISTORY_SHOW_EMAIL_ADDRESSES, true);
+		store.setDefault(UIPreferences.RESOURCEHISTORY_SHOW_NOTES, false);
+		store.setDefault(UIPreferences.RESOURCEHISTORY_SHOW_COMMENT_WRAP, true);
+		store.setDefault(UIPreferences.RESOURCEHISTORY_SHOW_REV_DETAIL, true);
+		store.setDefault(UIPreferences.RESOURCEHISTORY_SHOW_REV_COMMENT, true);
+		store.setDefault(UIPreferences.RESOURCEHISTORY_SHOW_TOOLTIPS, false);
+		store.setDefault(UIPreferences.RESOURCEHISTORY_SHOW_ALL_BRANCHES, false);
+		store.setDefault(UIPreferences.RESOURCEHISTORY_SHOW_ADDITIONAL_REFS, true);
+		store.setDefault(UIPreferences.RESOURCEHISTORY_FOLLOW_RENAMES, false);
+		store.setDefault(UIPreferences.RESOURCEHISTORY_COMPARE_MODE, false);
+
+		store.setDefault(UIPreferences.DECORATOR_RECOMPUTE_ANCESTORS, true);
+		store.setDefault(UIPreferences.DECORATOR_FILETEXT_DECORATION,
+				GitLightweightDecorator.DecorationHelper.FILE_FORMAT_DEFAULT);
+		store.setDefault(UIPreferences.DECORATOR_FOLDERTEXT_DECORATION,
+				GitLightweightDecorator.DecorationHelper.FOLDER_FORMAT_DEFAULT);
+		store.setDefault(UIPreferences.DECORATOR_PROJECTTEXT_DECORATION,
+				GitLightweightDecorator.DecorationHelper.PROJECT_FORMAT_DEFAULT);
+		store.setDefault(UIPreferences.DECORATOR_SHOW_TRACKED_ICON, true);
+		store.setDefault(UIPreferences.DECORATOR_SHOW_UNTRACKED_ICON, true);
+		store.setDefault(UIPreferences.DECORATOR_SHOW_STAGED_ICON, true);
+		store.setDefault(UIPreferences.DECORATOR_SHOW_CONFLICTS_ICON, true);
+		store.setDefault(UIPreferences.DECORATOR_SHOW_ASSUME_VALID_ICON, true);
+		store.setDefault(UIPreferences.DECORATOR_SHOW_DIRTY_ICON, false);
+
+		w = new int[] { 500, 500 };
+		store.setDefault(UIPreferences.RESOURCEHISTORY_GRAPH_SPLIT, UIPreferences.intArrayToString(w));
+		w = new int[] { 700, 300 };
+		store.setDefault(UIPreferences.RESOURCEHISTORY_REV_SPLIT, UIPreferences.intArrayToString(w));
+
+		store.setDefault(UIPreferences.FINDTOOLBAR_IGNORE_CASE, true);
+		store.setDefault(UIPreferences.FINDTOOLBAR_FIND_IN, 2);
+		store.setDefault(UIPreferences.COMMIT_DIALOG_HARD_WRAP_MESSAGE, true);
+		store.setDefault(UIPreferences.COMMIT_DIALOG_SIGNED_OFF_BY, false);
+
+		store.setDefault(UIPreferences.REFESH_ON_INDEX_CHANGE, true);
+		store.setDefault(UIPreferences.REFESH_ONLY_WHEN_ACTIVE, true);
+		store.setDefault(UIPreferences.DEFAULT_REPO_DIR, new File(FS.DETECTED.userHome(), "git").getPath()); //$NON-NLS-1$
+		store.setDefault(UIPreferences.SHOW_REBASE_CONFIRM, true);
+		store.setDefault(UIPreferences.SHOW_INITIAL_CONFIG_DIALOG, true);
+		store.setDefault(UIPreferences.SHOW_HOME_DIR_WARNING, true);
+		store.setDefault(UIPreferences.SHOW_GIT_PREFIX_WARNING, true);
+		store.setDefault(UIPreferences.SHOW_DETACHED_HEAD_WARNING, true);
+
+
+		store.setDefault(UIPreferences.SYNC_VIEW_CHANGESET_LABEL_FORMAT,
+				UIPreferences.DEFAULT_CHANGESET_FORMAT);
+		store.setDefault(UIPreferences.SYNC_VIEW_ALWAYS_SHOW_CHANGESET_MODEL,
+				false);
+		store.setDefault(UIPreferences.SYNC_VIEW_FETCH_BEFORE_LAUNCH, true);
+		store.setDefault(UIPreferences.DATE_FORMAT,
+				UIPreferences.DEFAULT_DATE_FORMAT);
+		store.setDefault(UIPreferences.HISTORY_MAX_NUM_COMMITS, 10000);
+		store.setDefault(UIPreferences.HISTORY_SHOW_TAG_SEQUENCE, false);
+		store.setDefault(UIPreferences.BLAME_IGNORE_WHITESPACE, false);
+		store.setDefault(UIPreferences.REMOTE_CONNECTION_TIMEOUT, 30 /* seconds */);
+		store.setDefault(UIPreferences.STAGING_VIEW_FILENAME_MODE, true);
+		store.setDefault(UIPreferences.CLONE_WIZARD_STORE_SECURESTORE, false);
+		store.setDefault(UIPreferences.COMMIT_DIALOG_HISTORY_SIZE, 10);
+		store.setDefault(UIPreferences.CHECKOUT_PROJECT_RESTORE, true);
+		store.setDefault(UIPreferences.HISTORY_MAX_TAG_LENGTH, 15);
+		store.setDefault(UIPreferences.HISTORY_MAX_BRANCH_LENGTH, 15);
+		store.setDefault(UIPreferences.CLONE_WIZARD_SHOW_DETAILED_FAILURE_DIALOG, true);
+	}
+
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/ResourcePropertyTester.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/ResourcePropertyTester.java
index 95ff4af..292d7b3 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/ResourcePropertyTester.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/ResourcePropertyTester.java
@@ -15,7 +15,7 @@
 
 import org.eclipse.core.expressions.PropertyTester;
 import org.eclipse.core.resources.IResource;
-import org.eclipse.egit.core.project.RepositoryMapping;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
 import org.eclipse.egit.ui.internal.trace.GitTraceLocation;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.lib.RepositoryState;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/SaveFilter.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/SaveFilter.java
index 8741ee1..14e64f4 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/SaveFilter.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/SaveFilter.java
@@ -16,7 +16,6 @@
 import org.eclipse.core.resources.mapping.ResourceMappingContext;
 import org.eclipse.core.resources.mapping.ResourceTraversal;
 import org.eclipse.core.runtime.CoreException;
-import org.eclipse.egit.ui.Activator;
 import org.eclipse.osgi.util.NLS;
 import org.eclipse.ui.IEditorPart;
 import org.eclipse.ui.ISaveableFilter;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/SecureStoreUtils.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/SecureStoreUtils.java
index e9ee7d0..29d5a29 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/SecureStoreUtils.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/SecureStoreUtils.java
@@ -11,8 +11,7 @@
 
 import java.io.IOException;
 
-import org.eclipse.egit.core.securestorage.UserPasswordCredentials;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.securestorage.UserPasswordCredentials;
 import org.eclipse.equinox.security.storage.StorageException;
 import org.eclipse.jgit.transport.URIish;
 
@@ -31,7 +30,7 @@
 			URIish uri) {
 		if (credentials != null && uri != null) {
 			try {
-				org.eclipse.egit.core.Activator.getDefault().getSecureStore()
+				org.eclipse.egit.core.internal.Activator.getDefault().getSecureStore()
 						.putCredentials(uri, credentials);
 			} catch (StorageException e) {
 				Activator.handleError(
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIIcons.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIIcons.java
index 319743c..e690e40 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIIcons.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIIcons.java
@@ -14,7 +14,6 @@
 import java.net.MalformedURLException;
 import java.net.URL;
 
-import org.eclipse.egit.ui.Activator;
 import org.eclipse.jface.resource.ImageDescriptor;
 
 /**
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIPreferences.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIPreferences.java
new file mode 100644
index 0000000..d8a2d29
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIPreferences.java
@@ -0,0 +1,228 @@
+/*******************************************************************************
+ * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
+ * Copyright (C) 2008, Roger C. Soares <rogersoares@intelinet.com.br>
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
+ * Copyright (C) 2010, Mathias Kinzler <mathias.kinzler@sap.com>
+ * Copyright (C) 2012, Daniel Megert <daniel_megert@ch.ibm.com>
+ * Copyright (C) 2013, Tobias Pfeifer <to.pfeifer@sap.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal;
+
+
+
+/**
+ * Preferences used by the EGit UI plug-in.
+ * <p>
+ * All plug-in preferences shall be referenced by a constant in this class.
+ */
+public class UIPreferences {
+	/** */
+	public final static String RESOURCEHISTORY_SHOW_RELATIVE_DATE = "resourcehistory_show_relative_date"; //$NON-NLS-1$
+	/** */
+	public final static String RESOURCEHISTORY_SHOW_EMAIL_ADDRESSES = "resourcehistory_show_email_addresses"; //$NON-NLS-1$
+	/** */
+	public final static String RESOURCEHISTORY_SHOW_NOTES = "resourcehistory_show_notes"; //$NON-NLS-1$
+	/** */
+	public final static String RESOURCEHISTORY_SHOW_COMMENT_WRAP = "resourcehistory_show_comment_wrap"; //$NON-NLS-1$
+	/** */
+	public static final String RESOURCEHISTORY_SHOW_COMMENT_FILL = "resourcehistory_fill_comment_paragraph"; //$NON-NLS-1$
+	/** */
+	public final static String RESOURCEHISTORY_SHOW_REV_DETAIL = "resourcehistory_show_rev_detail"; //$NON-NLS-1$
+	/** */
+	public final static String RESOURCEHISTORY_SHOW_REV_COMMENT = "resourcehistory_show_rev_comment"; //$NON-NLS-1$
+	/** */
+	public final static String RESOURCEHISTORY_GRAPH_SPLIT = "resourcehistory_graph_split"; //$NON-NLS-1$
+	/** */
+	public final static String RESOURCEHISTORY_REV_SPLIT = "resourcehistory_rev_split"; //$NON-NLS-1$
+	/** */
+	public final static String RESOURCEHISTORY_SHOW_TOOLTIPS = "resourcehistory_show_tooltips"; //$NON-NLS-1$
+	/** */
+	public final static String RESOURCEHISTORY_SHOW_FINDTOOLBAR = "resourcehistory_show_findtoolbar"; //$NON-NLS-1$
+	/** */
+	public final static String RESOURCEHISTORY_SHOW_ALL_BRANCHES = "resourcehistory_show_all_branches"; //$NON-NLS-1$
+	/** */
+	public final static String RESOURCEHISTORY_SHOW_ADDITIONAL_REFS = "resourcehistory_show_additionalrefs"; //$NON-NLS-1$
+	/** */
+	public static final String RESOURCEHISTORY_FOLLOW_RENAMES = "resourcehistory_follow_renames"; //$NON-NLS-1$
+	/** */
+	public final static String RESOURCEHISTORY_COMPARE_MODE = "resourcehistory_compare_mode"; //$NON-NLS-1$
+	/** */
+	public final static String FINDTOOLBAR_IGNORE_CASE = "findtoolbar_ignore_case"; //$NON-NLS-1$
+	/** */
+	public final static String FINDTOOLBAR_COMMIT_ID = "findtoolbar_commit_id"; //$NON-NLS-1$
+	/** */
+	public final static String FINDTOOLBAR_COMMENTS = "findtoolbar_comments"; //$NON-NLS-1$
+	/** */
+	public final static String FINDTOOLBAR_AUTHOR = "findtoolbar_author"; //$NON-NLS-1$
+	/** */
+	public final static String FINDTOOLBAR_COMMITTER = "findtoolbar_committer"; //$NON-NLS-1$
+	/** */
+	public final static String FINDTOOLBAR_FIND_IN = "findtoolbar_find_in"; //$NON-NLS-1$
+	/** */
+	public final static String COMMIT_DIALOG_HARD_WRAP_MESSAGE = "commit_dialog_hard_wrap_message"; //$NON-NLS-1$
+	/** */
+	public final static String COMMIT_DIALOG_SIGNED_OFF_BY = "commit_dialog_signed_off_by"; //$NON-NLS-1$
+	/** */
+	public final static String COMMIT_DIALOG_HISTORY_SIZE = "commit_dialog_history_size"; //$NON-NLS-1$
+	/** */
+	public final static String COMMIT_DIALOG_HISTORY_MESSAGES = "commit_dialog_history_messages"; //$NON-NLS-1$
+	/** */
+	public final static String COMMIT_DIALOG_INCLUDE_UNTRACKED = "commit_dialog_include_untracked"; //$NON-NLS-1$
+	/** */
+	public final static String CHECKOUT_PROJECT_RESTORE = "restore_projects_on_checkout"; //$NON-NLS-1$
+	/** */
+	public final static String THEME_CommitGraphNormalFont = "org.eclipse.egit.ui.CommitGraphNormalFont"; //$NON-NLS-1$
+	/** */
+	public final static String THEME_CommitGraphHighlightFont = "org.eclipse.egit.ui.CommitGraphHighlightFont"; //$NON-NLS-1$
+	/** */
+	public final static String THEME_CommitMessageFont = "org.eclipse.egit.ui.CommitMessageFont"; //$NON-NLS-1$
+	/** */
+	public final static String THEME_CommitMessageEditorFont = "org.eclipse.egit.ui.CommitMessageEditorFont"; //$NON-NLS-1$
+	/** */
+	public final static String THEME_UncommittedChangeForegroundColor = "org.eclipse.egit.ui.UncommittedChangeForegroundColor"; //$NON-NLS-1$
+	/** */
+	public final static String THEME_UncommittedChangeBackgroundColor = "org.eclipse.egit.ui.UncommittedChangeBackgroundColor"; //$NON-NLS-1$
+	/** */
+	public final static String THEME_UncommittedChangeFont = "org.eclipse.egit.ui.UncommittedChangeFont"; //$NON-NLS-1$
+	/** */
+	public final static String THEME_DiffHunkBackgroundColor = "org.eclipse.egit.ui.DiffHunkBackgroundColor"; //$NON-NLS-1$
+	/** */
+	public final static String THEME_DiffHunkForegroundColor = "org.eclipse.egit.ui.DiffHunkForegroundColor"; //$NON-NLS-1$
+	/** */
+	public final static String THEME_DiffHeadlineBackgroundColor = "org.eclipse.egit.ui.DiffHeadlineBackgroundColor"; //$NON-NLS-1$
+	/** */
+	public final static String THEME_DiffHeadlineForegroundColor = "org.eclipse.egit.ui.DiffHeadlineForegroundColor"; //$NON-NLS-1$
+	/** */
+	public final static String THEME_DiffHeadlineFont = "org.eclipse.egit.ui.DiffHeadlineFont"; //$NON-NLS-1$
+	/** */
+	public final static String THEME_DiffAddBackgroundColor = "org.eclipse.egit.ui.DiffAddBackgroundColor"; //$NON-NLS-1$
+	/** */
+	public final static String THEME_DiffAddForegroundColor = "org.eclipse.egit.ui.DiffAddForegroundColor"; //$NON-NLS-1$
+	/** */
+	public final static String THEME_DiffRemoveBackgroundColor = "org.eclipse.egit.ui.DiffRemoveBackgroundColor"; //$NON-NLS-1$
+	/** */
+	public final static String THEME_DiffRemoveForegroundColor = "org.eclipse.egit.ui.DiffRemoveForegroundColor"; //$NON-NLS-1$
+	/** */
+	public final static String DECORATOR_RECOMPUTE_ANCESTORS = "decorator_recompute_ancestors"; //$NON-NLS-1$
+	/** */
+	public final static String DECORATOR_FILETEXT_DECORATION = "decorator_filetext_decoration"; //$NON-NLS-1$
+	/** */
+	public final static String DECORATOR_FOLDERTEXT_DECORATION = "decorator_foldertext_decoration"; //$NON-NLS-1$
+	/** */
+	public final static String DECORATOR_PROJECTTEXT_DECORATION = "decorator_projecttext_decoration"; //$NON-NLS-1$
+	/** */
+	public final static String DECORATOR_SHOW_TRACKED_ICON = "decorator_show_tracked_icon"; //$NON-NLS-1$
+	/** */
+	public final static String DECORATOR_SHOW_UNTRACKED_ICON = "decorator_show_untracked_icon"; //$NON-NLS-1$
+	/** */
+	public final static String DECORATOR_SHOW_STAGED_ICON = "decorator_show_staged_icon"; //$NON-NLS-1$
+	/** */
+	public final static String DECORATOR_SHOW_CONFLICTS_ICON = "decorator_show_conflicts_icon"; //$NON-NLS-1$
+	/** */
+	public final static String DECORATOR_SHOW_ASSUME_VALID_ICON = "decorator_show_assume_valid_icon"; //$NON-NLS-1$
+	/** */
+	public final static String DECORATOR_SHOW_DIRTY_ICON = "decorator_show_dirty_icon"; //$NON-NLS-1$
+	/** */
+	public final static String SYNC_VIEW_CHANGESET_LABEL_FORMAT = "sync_view_changeset_pattern"; //$NON-NLS-1$
+	/** */
+	public final static String SYNC_VIEW_ALWAYS_SHOW_CHANGESET_MODEL = "sync_view_show_changeset_model"; //$NON-NLS-1$
+	/** */
+	public final static String SYNC_VIEW_LAST_SELECTED_MODEL = "sync_view_last_selected_model"; //$NON-NLS-1$
+	/** */
+	public static final String SYNC_VIEW_FETCH_BEFORE_LAUNCH = "sync_view_fetch_before_launch"; //$NON-NLS-1$
+	/** */
+	public final static String DATE_FORMAT = "date_format"; //$NON-NLS-1$
+	/** */
+	public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";  //$NON-NLS-1$
+	/** */
+	public static final String DEFAULT_CHANGESET_FORMAT = "[{author}] ({date}) {short_message}"; //$NON-NLS-1$
+	/** */
+	public static final String REFESH_ON_INDEX_CHANGE = "refesh_on_index_change"; //$NON-NLS-1$
+	/** */
+	public static final String REFESH_ONLY_WHEN_ACTIVE = "refesh_only_when_active"; //$NON-NLS-1$
+	/** */
+	public static final String REMOTE_CONNECTION_TIMEOUT = "remote_connection_timeout"; //$NON-NLS-1$
+	/** */
+	public static final String DEFAULT_REPO_DIR = "default_repository_dir"; //$NON-NLS-1$
+	/** */
+	public static final String MERGE_MODE = "merge_mode"; //$NON-NLS-1$
+	/** */
+	public static final String SHOW_REBASE_CONFIRM = "show_rebase_confirm"; //$NON-NLS-1$
+	/** */
+	public static final String SHOW_INITIAL_CONFIG_DIALOG = "show_initial_config_dialog"; //$NON-NLS-1$
+	/** */
+	public static final String SHOW_HOME_DIR_WARNING = "show_home_drive_warning"; //$NON-NLS-1$
+	/** */
+	public static final String SHOW_GIT_PREFIX_WARNING = "show_git_prefix_warning"; //$NON-NLS-1$
+	/** */
+	public static final String SHOW_DETACHED_HEAD_WARNING = "show_detached_head_warning"; //$NON-NLS-1$
+	/** */
+	public static final String TREE_COMPARE_SHOW_EQUALS = "CompareTreeView_ShowEquals"; //$NON-NLS-1$
+	/** */
+	public static final String HISTORY_MAX_NUM_COMMITS = "HistoryView_MaxNumberOfCommmits"; //$NON-NLS-1$
+	/** */
+	public static final String HISTORY_MAX_TAG_LENGTH = "HistoryView_MaxTagLength"; //$NON-NLS-1$
+	/** */
+	public static final String HISTORY_MAX_BRANCH_LENGTH = "HistoryView_MaxBranchLength"; //$NON-NLS-1$
+	/** */
+	public static final String HISTORY_SHOW_TAG_SEQUENCE = "HistoryView_ShowTagSequence"; //$NON-NLS-1$
+	/** */
+	public static final String STAGING_VIEW_SHOW_NEW_COMMITS = "StagingView_ShowNewCommits"; //$NON-NLS-1$
+	/** */
+	public static final String STAGING_VIEW_COLUMN_LAYOUT = "StagingView_ColumnLayout"; //$NON-NLS-1$
+	/** */
+	public static final String STAGING_VIEW_SYNC_SELECTION = "StagingView_SyncWithSelection"; //$NON-NLS-1$
+	/** */
+	public static final String STAGING_VIEW_FILENAME_MODE = "StagingView_FileNameMode"; //$NON-NLS-1$
+	/** */
+	public static final String PAGE_COMMIT_PREFERENCES = "org.eclipse.egit.ui.internal.preferences.CommitDialogPreferencePage"; //$NON-NLS-1$
+	/** */
+	public static final String BLAME_IGNORE_WHITESPACE = "Blame_IgnoreWhitespace"; //$NON-NLS-1$
+	/** */
+	public static final String CLONE_WIZARD_STORE_SECURESTORE = "CloneWizard_StoreInSecureStore"; //$NON-NLS-1$
+	/** */
+	public static final String CLONE_WIZARD_IMPORT_PROJECTS = "CloneWizard_ImportProjects"; //$NON-NLS-1$
+	/** */
+	public static final String CLONE_WIZARD_SHOW_DETAILED_FAILURE_DIALOG = "CloneWizard_ShowDetailedFailureDialog"; //$NON-NLS-1$
+
+	/**
+	 * Converts a persisted String separated with commas to an integer array
+	 *
+	 * @param value
+	 *            the String value
+	 * @param cnt
+	 *            number of entries in the returned array
+	 * @return the preference values for the array.
+	 */
+	public static int[] stringToIntArray(final String value, final int cnt) {
+		final int[] r = new int[cnt];
+		if (value != null) {
+			final String[] e = value.split(","); //$NON-NLS-1$
+			for (int i = 0; i < Math.min(e.length, r.length); i++)
+				r[i] = Integer.parseInt(e[i].trim());
+		}
+		return r;
+	}
+
+	/**
+	 * Converts an integer array into a String separated by commas
+	 *
+	 * @param data
+	 *            integers to store
+	 * @return the String
+	 */
+	public static String intArrayToString(final int[] data) {
+		final StringBuilder s = new StringBuilder();
+		for (int i = 0; i < data.length; i++) {
+			if (i > 0)
+				s.append(',');
+			s.append(data[i]);
+		}
+		return s.toString();
+	}
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIUtils.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIUtils.java
new file mode 100644
index 0000000..0cefca5
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIUtils.java
@@ -0,0 +1,676 @@
+/*******************************************************************************
+ * Copyright (c) 2010, 2012 SAP AG and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Mathias Kinzler (SAP AG) - initial implementation
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.NotEnabledException;
+import org.eclipse.core.commands.NotHandledException;
+import org.eclipse.core.commands.common.NotDefinedException;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.egit.ui.internal.components.RefContentProposal;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.bindings.keys.KeyStroke;
+import org.eclipse.jface.bindings.keys.ParseException;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.fieldassist.ContentProposalAdapter;
+import org.eclipse.jface.fieldassist.ControlDecoration;
+import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
+import org.eclipse.jface.fieldassist.IContentProposal;
+import org.eclipse.jface.fieldassist.IContentProposalProvider;
+import org.eclipse.jface.fieldassist.TextContentAdapter;
+import org.eclipse.jface.resource.FontRegistry;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ResourceManager;
+import org.eclipse.jface.viewers.AbstractTreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Resource;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.ToolBar;
+import org.eclipse.swt.widgets.ToolItem;
+import org.eclipse.swt.widgets.Widget;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchCommandConstants;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.ContributionItemFactory;
+import org.eclipse.ui.handlers.IHandlerService;
+import org.eclipse.ui.keys.IBindingService;
+
+/**
+ * Some utilities for UI code
+ */
+public class UIUtils {
+	/**
+	 * these activate the content assist; alphanumeric, space plus some expected
+	 * special chars
+	 */
+	private static final char[] VALUE_HELP_ACTIVATIONCHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123457890*@ <>".toCharArray(); //$NON-NLS-1$
+
+	/**
+	 * A keystroke for a "submit" action, see {@link #isSubmitKeyEvent(KeyEvent)}
+	 */
+	public static final KeyStroke SUBMIT_KEY_STROKE = KeyStroke.getInstance(SWT.MOD1, SWT.CR);
+
+	/**
+	 * Handles a "previously used values" content assist.
+	 * <p>
+	 * Adding this to a text field will enable "content assist" by keeping track
+	 * of the previously used valued for this field. The previously used values
+	 * will be shown in the order they were last used (most recently used ones
+	 * coming first in the list) and the number of entries is limited.
+	 * <p>
+	 * A "bulb" decorator will indicate that content assist is available for the
+	 * field, and a tool tip is provided giving more information.
+	 * <p>
+	 * Content assist is activated by either typing in the field or by using a
+	 * dedicated key stroke which is indicated in the tool tip. The list will be
+	 * filtered with the content already in the text field with '*' being usable
+	 * as wild card.
+	 * <p>
+	 * Note that the application must issue a call to {@link #updateProposals()}
+	 * in order to add a new value to the "previously used values" list.
+	 * <p>
+	 * The list will be persisted in the plug-in dialog settings.
+	 *
+	 * @noextend not to be extended by clients
+	 * @noimplement not to be implemented by clients, use
+	 *              {@link UIUtils#addPreviousValuesContentProposalToText(Text, String)}
+	 *              to create instances of this
+	 */
+	public interface IPreviousValueProposalHandler {
+		/**
+		 * Updates the proposal list from the value in the text field.
+		 * <p>
+		 * The value will be truncated to the first 2000 characters in order to
+		 * limit data size.
+		 * <p>
+		 * Note that this must be called in the UI thread, since it accesses the
+		 * text field.
+		 * <p>
+		 * If the value is already in the list, it will become the first entry,
+		 * otherwise it will be added at the beginning. Note that empty Strings
+		 * will not be stored. The length of the list is limited, and the
+		 * "oldest" entries will be removed once the limit is exceeded.
+		 * <p>
+		 * This call should only be issued if the value in the text field is
+		 * "valid" in terms of the application.
+		 */
+		public void updateProposals();
+	}
+
+	/**
+	 * Used for
+	 * {@link UIUtils#addRefContentProposalToText(Text, Repository, IRefListProvider)}
+	 */
+	public interface IRefListProvider {
+		/**
+		 * @return the List of {@link Ref}s to propose
+		 */
+		public List<Ref> getRefList();
+	}
+
+	/**
+	 * @param id
+	 *            see {@link FontRegistry#get(String)}
+	 * @return the font
+	 */
+	public static Font getFont(final String id) {
+		return PlatformUI.getWorkbench().getThemeManager().getCurrentTheme()
+				.getFontRegistry().get(id);
+	}
+
+	/**
+	 * @param id
+	 *            see {@link FontRegistry#getBold(String)}
+	 * @return the font
+	 */
+	public static Font getBoldFont(final String id) {
+		return PlatformUI.getWorkbench().getThemeManager().getCurrentTheme()
+				.getFontRegistry().getBold(id);
+	}
+
+	/**
+	 * @param id
+	 *            see {@link FontRegistry#getItalic(String)}
+	 * @return the font
+	 */
+	public static Font getItalicFont(final String id) {
+		return PlatformUI.getWorkbench().getThemeManager().getCurrentTheme()
+				.getFontRegistry().getItalic(id);
+	}
+
+	/**
+	 * Adds little bulb decoration to given control. Bulb will appear in top
+	 * left corner of control after giving focus for this control.
+	 *
+	 * After clicking on bulb image text from <code>tooltip</code> will appear.
+	 *
+	 * @param control
+	 *            instance of {@link Control} object with should be decorated
+	 * @param tooltip
+	 *            text value which should appear after clicking on bulb image.
+	 */
+	public static void addBulbDecorator(final Control control,
+			final String tooltip) {
+		ControlDecoration dec = new ControlDecoration(control, SWT.TOP
+				| SWT.LEFT);
+
+		dec.setImage(FieldDecorationRegistry.getDefault().getFieldDecoration(
+				FieldDecorationRegistry.DEC_CONTENT_PROPOSAL).getImage());
+
+		dec.setShowOnlyOnFocus(true);
+		dec.setShowHover(true);
+
+		dec.setDescriptionText(tooltip);
+	}
+
+	/**
+	 * Adds a "previously used values" content proposal handler to a text field.
+	 * <p>
+	 * The keyboard shortcut will be "M1+SPACE" and the list will be limited to
+	 * 10 values.
+	 *
+	 * @param textField
+	 *            the text field
+	 * @param preferenceKey
+	 *            the key under which to store the "previously used values" in
+	 *            the dialog settings
+	 * @return the handler the proposal handler
+	 */
+	public static IPreviousValueProposalHandler addPreviousValuesContentProposalToText(
+			final Text textField, final String preferenceKey) {
+		KeyStroke stroke;
+		try {
+			stroke = KeyStroke.getInstance("M1+SPACE"); //$NON-NLS-1$
+			addBulbDecorator(textField, NLS.bind(
+					UIText.UIUtils_PressShortcutMessage, stroke.format()));
+		} catch (ParseException e1) {
+			Activator.handleError(e1.getMessage(), e1, false);
+			stroke = null;
+			addBulbDecorator(textField,
+					UIText.UIUtils_StartTypingForPreviousValuesMessage);
+		}
+
+		IContentProposalProvider cp = new IContentProposalProvider() {
+
+			public IContentProposal[] getProposals(String contents, int position) {
+
+				List<IContentProposal> resultList = new ArrayList<IContentProposal>();
+
+				// make the simplest possible pattern check: allow "*"
+				// for multiple characters
+				String patternString = contents;
+				// ignore spaces in the beginning
+				while (patternString.length() > 0
+						&& patternString.charAt(0) == ' ') {
+					patternString = patternString.substring(1);
+				}
+
+				// we quote the string as it may contain spaces
+				// and other stuff colliding with the Pattern
+				patternString = Pattern.quote(patternString);
+
+				patternString = patternString.replaceAll("\\x2A", ".*"); //$NON-NLS-1$ //$NON-NLS-2$
+
+				// make sure we add a (logical) * at the end
+				if (!patternString.endsWith(".*")) { //$NON-NLS-1$
+					patternString = patternString + ".*"; //$NON-NLS-1$
+				}
+
+				// let's compile a case-insensitive pattern (assumes ASCII only)
+				Pattern pattern;
+				try {
+					pattern = Pattern.compile(patternString,
+							Pattern.CASE_INSENSITIVE);
+				} catch (PatternSyntaxException e) {
+					pattern = null;
+				}
+
+				String[] proposals = org.eclipse.egit.ui.internal.Activator.getDefault()
+						.getDialogSettings().getArray(preferenceKey);
+
+				if (proposals != null)
+					for (final String uriString : proposals) {
+
+						if (pattern != null
+								&& !pattern.matcher(uriString).matches())
+							continue;
+
+						IContentProposal propsal = new IContentProposal() {
+
+							public String getLabel() {
+								return null;
+							}
+
+							public String getDescription() {
+								return null;
+							}
+
+							public int getCursorPosition() {
+								return 0;
+							}
+
+							public String getContent() {
+								return uriString;
+							}
+						};
+						resultList.add(propsal);
+					}
+
+				return resultList.toArray(new IContentProposal[resultList
+						.size()]);
+			}
+		};
+
+		ContentProposalAdapter adapter = new ContentProposalAdapter(textField,
+				new TextContentAdapter(), cp, stroke,
+				VALUE_HELP_ACTIVATIONCHARS);
+		// set the acceptance style to always replace the complete content
+		adapter
+				.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);
+
+		return new IPreviousValueProposalHandler() {
+			public void updateProposals() {
+				String value = textField.getText();
+				// don't store empty values
+				if (value.length() > 0) {
+					// we don't want to save too much in the preferences
+					if (value.length() > 2000) {
+						value = value.substring(0, 1999);
+					}
+					// now we need to mix the value into the list
+					IDialogSettings settings = org.eclipse.egit.ui.internal.Activator
+							.getDefault().getDialogSettings();
+					String[] existingValues = settings.getArray(preferenceKey);
+					if (existingValues == null) {
+						existingValues = new String[] { value };
+						settings.put(preferenceKey, existingValues);
+					} else {
+
+						List<String> values = new ArrayList<String>(
+								existingValues.length + 1);
+
+						for (String existingValue : existingValues)
+							values.add(existingValue);
+						// if it is already the first value, we don't need to do
+						// anything
+						if (values.indexOf(value) == 0)
+							return;
+
+						values.remove(value);
+						// we insert at the top
+						values.add(0, value);
+						// make sure to not store more than the maximum number
+						// of values
+						while (values.size() > 10)
+							values.remove(values.size() - 1);
+
+						settings.put(preferenceKey, values
+								.toArray(new String[values.size()]));
+					}
+				}
+			}
+		};
+	}
+
+	/**
+	 * Adds a content proposal for {@link Ref}s (branches, tags...) to a text
+	 * field
+	 *
+	 * @param textField
+	 *            the text field
+	 * @param repository
+	 *            the repository
+	 * @param refListProvider
+	 *            provides the {@link Ref}s to show in the proposal
+	 */
+	public static final void addRefContentProposalToText(final Text textField,
+			final Repository repository, final IRefListProvider refListProvider) {
+		KeyStroke stroke;
+		try {
+			stroke = KeyStroke.getInstance("M1+SPACE"); //$NON-NLS-1$
+			UIUtils.addBulbDecorator(textField, NLS.bind(
+					UIText.UIUtils_PressShortcutMessage, stroke.format()));
+		} catch (ParseException e1) {
+			Activator.handleError(e1.getMessage(), e1, false);
+			stroke = null;
+			UIUtils.addBulbDecorator(textField,
+					UIText.UIUtils_StartTypingForPreviousValuesMessage);
+		}
+
+		IContentProposalProvider cp = new IContentProposalProvider() {
+			public IContentProposal[] getProposals(String contents, int position) {
+				List<IContentProposal> resultList = new ArrayList<IContentProposal>();
+
+				// make the simplest possible pattern check: allow "*"
+				// for multiple characters
+				String patternString = contents;
+				// ignore spaces in the beginning
+				while (patternString.length() > 0
+						&& patternString.charAt(0) == ' ') {
+					patternString = patternString.substring(1);
+				}
+
+				// we quote the string as it may contain spaces
+				// and other stuff colliding with the Pattern
+				patternString = Pattern.quote(patternString);
+
+				patternString = patternString.replaceAll("\\x2A", ".*"); //$NON-NLS-1$ //$NON-NLS-2$
+
+				// make sure we add a (logical) * at the end
+				if (!patternString.endsWith(".*")) { //$NON-NLS-1$
+					patternString = patternString + ".*"; //$NON-NLS-1$
+				}
+
+				// let's compile a case-insensitive pattern (assumes ASCII only)
+				Pattern pattern;
+				try {
+					pattern = Pattern.compile(patternString,
+							Pattern.CASE_INSENSITIVE);
+				} catch (PatternSyntaxException e) {
+					pattern = null;
+				}
+
+				List<Ref> proposals = refListProvider.getRefList();
+
+				if (proposals != null)
+					for (final Ref ref : proposals) {
+						final String shortenedName = Repository
+								.shortenRefName(ref.getName());
+						if (pattern != null
+								&& !pattern.matcher(ref.getName()).matches()
+								&& !pattern.matcher(shortenedName).matches())
+							continue;
+
+						IContentProposal propsal = new RefContentProposal(
+								repository, ref);
+						resultList.add(propsal);
+					}
+
+				return resultList.toArray(new IContentProposal[resultList
+						.size()]);
+			}
+		};
+
+		ContentProposalAdapter adapter = new ContentProposalAdapter(textField,
+				new TextContentAdapter(), cp, stroke,
+				UIUtils.VALUE_HELP_ACTIVATIONCHARS);
+		// set the acceptance style to always replace the complete content
+		adapter
+				.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);
+	}
+
+	/**
+	 * Set enabled state of the control and all its children
+	 * @param control
+	 * @param enable
+	 */
+	public static void setEnabledRecursively(final Control control,
+			final boolean enable) {
+		control.setEnabled(enable);
+		if (control instanceof Composite)
+			for (final Control child : ((Composite) control).getChildren())
+				setEnabledRecursively(child, enable);
+	}
+
+	/**
+	 * Dispose of the resource when the widget is disposed
+	 *
+	 * @param widget
+	 * @param resource
+	 */
+	public static void hookDisposal(Widget widget, final Resource resource) {
+		if (widget == null || resource == null)
+			return;
+
+		widget.addDisposeListener(new DisposeListener() {
+
+			public void widgetDisposed(DisposeEvent e) {
+				resource.dispose();
+			}
+		});
+	}
+
+	/**
+	 * Dispose of the resource manager when the widget is disposed
+	 *
+	 * @param widget
+	 * @param resources
+	 */
+	public static void hookDisposal(Widget widget,
+			final ResourceManager resources) {
+		if (widget == null || resources == null)
+			return;
+
+		widget.addDisposeListener(new DisposeListener() {
+
+			public void widgetDisposed(DisposeEvent e) {
+				resources.dispose();
+			}
+		});
+	}
+
+	/**
+	 * Get editor image for path
+	 *
+	 * @param path
+	 * @return image descriptor
+	 */
+	public static ImageDescriptor getEditorImage(final String path) {
+		if (path != null && path.length() > 0) {
+			final String name = new Path(path).lastSegment();
+			if (name != null)
+				return PlatformUI.getWorkbench().getEditorRegistry()
+						.getImageDescriptor(name);
+		}
+		return PlatformUI.getWorkbench().getSharedImages()
+				.getImageDescriptor(ISharedImages.IMG_OBJ_FILE);
+	}
+
+	/**
+	 * Get size of image descriptor as point.
+	 *
+	 * @param descriptor
+	 * @return size
+	 */
+	public static Point getSize(ImageDescriptor descriptor) {
+		ImageData data = descriptor.getImageData();
+		if (data == null)
+			return new Point(0, 0);
+		return new Point(data.width, data.height);
+	}
+
+	/**
+	 * Add expand all and collapse all toolbar items to the given toolbar bound
+	 * to the given tree viewer
+	 *
+	 * @param toolbar
+	 * @param viewer
+	 * @return given toolbar
+	 */
+	public static ToolBar addExpansionItems(final ToolBar toolbar,
+			final AbstractTreeViewer viewer) {
+		ToolItem collapseItem = new ToolItem(toolbar, SWT.PUSH);
+		Image collapseImage = UIIcons.COLLAPSEALL.createImage();
+		UIUtils.hookDisposal(collapseItem, collapseImage);
+		collapseItem.setImage(collapseImage);
+		collapseItem.setToolTipText(UIText.UIUtils_CollapseAll);
+		collapseItem.addSelectionListener(new SelectionAdapter() {
+
+			public void widgetSelected(SelectionEvent e) {
+				viewer.collapseAll();
+			}
+
+		});
+
+		ToolItem expandItem = new ToolItem(toolbar, SWT.PUSH);
+		Image expandImage = UIIcons.EXPAND_ALL.createImage();
+		UIUtils.hookDisposal(expandItem, expandImage);
+		expandItem.setImage(expandImage);
+		expandItem.setToolTipText(UIText.UIUtils_ExpandAll);
+		expandItem.addSelectionListener(new SelectionAdapter() {
+
+			public void widgetSelected(SelectionEvent e) {
+				viewer.expandAll();
+			}
+
+		});
+		return toolbar;
+	}
+
+	/**
+	 * Get dialog bound settings for given class using standard section name
+	 *
+	 * @param clazz
+	 * @return dialog setting
+	 */
+	public static IDialogSettings getDialogBoundSettings(final Class<?> clazz) {
+		return getDialogSettings(clazz.getName() + ".dialogBounds"); //$NON-NLS-1$
+	}
+
+	/**
+	 * Get dialog settings for given section name
+	 *
+	 * @param sectionName
+	 * @return dialog settings
+	 */
+	public static IDialogSettings getDialogSettings(final String sectionName) {
+		IDialogSettings settings = Activator.getDefault().getDialogSettings();
+		IDialogSettings section = settings.getSection(sectionName);
+		if (section == null)
+			section = settings.addNewSection(sectionName);
+		return section;
+	}
+
+	/**
+	 * Is viewer in a usable state?
+	 *
+	 * @param viewer
+	 * @return true if usable, false if null or underlying control is null or
+	 *         disposed
+	 */
+	public static boolean isUsable(final Viewer viewer) {
+		return viewer != null && isUsable(viewer.getControl());
+	}
+
+	/**
+	 * Is control usable?
+	 *
+	 * @param control
+	 * @return true if usable, false if null or disposed
+	 */
+	public static boolean isUsable(final Control control) {
+		return control != null && !control.isDisposed();
+	}
+
+	/**
+	 * Run command with specified id
+	 *
+	 * @param service
+	 * @param id
+	 */
+	public static void executeCommand(IHandlerService service, String id) {
+		executeCommand(service, id, null);
+	}
+
+	/**
+	 * Run command with specified id
+	 *
+	 * @param service
+	 * @param id
+	 * @param event
+	 */
+	public static void executeCommand(IHandlerService service, String id,
+			Event event) {
+		try {
+			service.executeCommand(id, event);
+		} catch (ExecutionException e) {
+			Activator.handleError(e.getMessage(), e, false);
+		} catch (NotDefinedException e) {
+			Activator.handleError(e.getMessage(), e, false);
+		} catch (NotEnabledException e) {
+			Activator.handleError(e.getMessage(), e, false);
+		} catch (NotHandledException e) {
+			Activator.handleError(e.getMessage(), e, false);
+		}
+	}
+
+	/**
+	 * Determine if the key event represents a "submit" action
+	 * (&lt;modifier&gt;+Enter).
+	 *
+	 * @param event
+	 * @return true, if it means submit, false otherwise
+	 */
+	public static boolean isSubmitKeyEvent(KeyEvent event) {
+		return (event.stateMask & SWT.MODIFIER_MASK) != 0
+				&& event.keyCode == SUBMIT_KEY_STROKE.getNaturalKey();
+	}
+
+	/**
+	 * Prompt for saving all dirty editors for resources in the working
+	 * directory of the specified repository.
+	 *
+	 * @param repository
+	 * @return true, if the user opted to continue, false otherwise
+	 * @see IWorkbench#saveAllEditors(boolean)
+	 */
+	public static boolean saveAllEditors(Repository repository) {
+		IWorkbench workbench = PlatformUI.getWorkbench();
+		IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
+		return workbench.saveAll(window, window, new RepositorySaveableFilter(repository), true);
+	}
+
+	/**
+	 * @param workbenchWindow the workbench window to use for creating the show in menu.
+	 * @return the show in menu
+	 */
+	public static MenuManager createShowInMenu(IWorkbenchWindow workbenchWindow) {
+		MenuManager showInSubMenu = new MenuManager(getShowInMenuLabel());
+		showInSubMenu.add(ContributionItemFactory.VIEWS_SHOW_IN.create(workbenchWindow));
+		return showInSubMenu;
+	}
+
+	private static String getShowInMenuLabel() {
+		IBindingService bindingService = (IBindingService) PlatformUI
+				.getWorkbench().getAdapter(IBindingService.class);
+		if (bindingService != null) {
+			String keyBinding = bindingService
+					.getBestActiveBindingFormattedFor(IWorkbenchCommandConstants.NAVIGATE_SHOW_IN_QUICK_MENU);
+			if (keyBinding != null)
+				return UIText.UIUtils_ShowInMenuLabel + '\t' + keyBinding;
+		}
+
+		return UIText.UIUtils_ShowInMenuLabel;
+	}
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/ValidationUtils.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/ValidationUtils.java
index 068ce1f..4618d6b 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/ValidationUtils.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/ValidationUtils.java
@@ -14,7 +14,6 @@
 import java.util.Collection;
 import java.util.Collections;
 
-import org.eclipse.egit.ui.Activator;
 import org.eclipse.jface.dialogs.IInputValidator;
 import org.eclipse.jgit.lib.RefDatabase;
 import org.eclipse.jgit.lib.Repository;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/AddToIndexAction.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/AddToIndexAction.java
index 0b809d8..e3564e9 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/AddToIndexAction.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/AddToIndexAction.java
@@ -9,7 +9,7 @@
  *******************************************************************************/
 package org.eclipse.egit.ui.internal.actions;
 
-import org.eclipse.egit.core.op.AddToIndexOperation;
+import org.eclipse.egit.core.internal.op.AddToIndexOperation;
 
 /**
  * An action to add files to a Git index.
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/AddToIndexActionHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/AddToIndexActionHandler.java
index 181428d..badd05b 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/AddToIndexActionHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/AddToIndexActionHandler.java
@@ -16,9 +16,9 @@
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.egit.core.op.AddToIndexOperation;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.core.internal.op.AddToIndexOperation;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.operations.GitScopeUtil;
 import org.eclipse.ui.IWorkbenchPart;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ApplyPatchActionHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ApplyPatchActionHandler.java
index 9219bd5..5606741 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ApplyPatchActionHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ApplyPatchActionHandler.java
@@ -17,7 +17,7 @@
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.runtime.CoreException;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.swt.custom.BusyIndicator;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.ui.handlers.HandlerUtil;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/AssumeUnchangedActionHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/AssumeUnchangedActionHandler.java
index 7daf36c..a98c456 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/AssumeUnchangedActionHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/AssumeUnchangedActionHandler.java
@@ -16,8 +16,8 @@
 import org.eclipse.core.commands.ExecutionException;
 import org.eclipse.core.resources.IResource;
 import org.eclipse.egit.core.internal.job.JobUtil;
-import org.eclipse.egit.core.op.AssumeUnchangedOperation;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.core.internal.op.AssumeUnchangedOperation;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 
 /**
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/BooleanPrefAction.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/BooleanPrefAction.java
index 3b79cd7..388ada6 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/BooleanPrefAction.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/BooleanPrefAction.java
@@ -13,7 +13,7 @@
 
 import java.io.IOException;
 
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.jface.action.Action;
 import org.eclipse.jface.preference.IPersistentPreferenceStore;
 import org.eclipse.jface.util.IPropertyChangeListener;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CompareIndexWithHeadActionHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CompareIndexWithHeadActionHandler.java
index c32c31e..7fb5b16 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CompareIndexWithHeadActionHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CompareIndexWithHeadActionHandler.java
@@ -19,9 +19,9 @@
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.runtime.IPath;
-import org.eclipse.egit.core.AdapterUtils;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.AdapterUtils;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.CompareUtils;
 import org.eclipse.egit.ui.internal.GitCompareFileRevisionEditorInput;
 import org.eclipse.egit.ui.internal.UIText;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CompareWithCommitActionHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CompareWithCommitActionHandler.java
index 29f08b1..bbad529 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CompareWithCommitActionHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CompareWithCommitActionHandler.java
@@ -15,7 +15,7 @@
 import org.eclipse.core.commands.ExecutionException;
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IResource;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.CompareUtils;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.dialogs.CompareTreeView;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CompareWithHeadActionHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CompareWithHeadActionHandler.java
index a1cce59..1079f9a 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CompareWithHeadActionHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CompareWithHeadActionHandler.java
@@ -17,8 +17,8 @@
 import org.eclipse.core.commands.ExecutionException;
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IResource;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.CompareUtils;
 import org.eclipse.egit.ui.internal.GitCompareFileRevisionEditorInput;
 import org.eclipse.egit.ui.internal.UIText;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CompareWithIndexActionHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CompareWithIndexActionHandler.java
index 5b53543..21a3740 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CompareWithIndexActionHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CompareWithIndexActionHandler.java
@@ -18,9 +18,9 @@
 import org.eclipse.core.commands.ExecutionException;
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.runtime.IPath;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
 import org.eclipse.egit.core.internal.util.ResourceUtil;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.CompareUtils;
 import org.eclipse.egit.ui.internal.GitCompareFileRevisionEditorInput;
 import org.eclipse.egit.ui.internal.UIText;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CompareWithPreviousActionHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CompareWithPreviousActionHandler.java
index 8841cd7..b3779f3 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CompareWithPreviousActionHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CompareWithPreviousActionHandler.java
@@ -28,8 +28,8 @@
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.jobs.ISchedulingRule;
 import org.eclipse.egit.core.internal.job.JobUtil;
-import org.eclipse.egit.core.op.IEGitOperation;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.op.IEGitOperation;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.CompareUtils;
 import org.eclipse.egit.ui.internal.GitCompareFileRevisionEditorInput;
 import org.eclipse.egit.ui.internal.UIText;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CompareWithRefActionHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CompareWithRefActionHandler.java
index 8a4101b..b3852f3 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CompareWithRefActionHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/CompareWithRefActionHandler.java
@@ -20,7 +20,7 @@
 import org.eclipse.core.commands.ExecutionException;
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IResource;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.CompareUtils;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.dialogs.CompareTargetSelectionDialog;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/DiscardChangesActionHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/DiscardChangesActionHandler.java
index 689fe8a..f507f7c 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/DiscardChangesActionHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/DiscardChangesActionHandler.java
@@ -21,9 +21,9 @@
 import org.eclipse.core.runtime.OperationCanceledException;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.egit.core.op.DiscardChangesOperation;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.core.internal.op.DiscardChangesOperation;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.operations.GitScopeUtil;
 import org.eclipse.jface.dialogs.MessageDialog;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/DisconnectActionHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/DisconnectActionHandler.java
index 253f0ba..4e07fe8 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/DisconnectActionHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/DisconnectActionHandler.java
@@ -18,8 +18,8 @@
 import org.eclipse.core.runtime.jobs.IJobChangeEvent;
 import org.eclipse.core.runtime.jobs.JobChangeAdapter;
 import org.eclipse.egit.core.internal.job.JobUtil;
-import org.eclipse.egit.core.op.DisconnectProviderOperation;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.core.internal.op.DisconnectProviderOperation;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.decorators.GitLightweightDecorator;
 
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/FetchActionHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/FetchActionHandler.java
index 664511d..f42f633 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/FetchActionHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/FetchActionHandler.java
@@ -14,7 +14,7 @@
 import org.eclipse.core.commands.ExecutionException;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.fetch.FetchWizard;
 import org.eclipse.jface.dialogs.ErrorDialog;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/MergeActionHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/MergeActionHandler.java
index b2b2dea..376f806 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/MergeActionHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/MergeActionHandler.java
@@ -20,8 +20,8 @@
 import org.eclipse.core.runtime.jobs.IJobChangeEvent;
 import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.core.runtime.jobs.JobChangeAdapter;
-import org.eclipse.egit.core.op.MergeOperation;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.op.MergeOperation;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.dialogs.BasicConfigurationDialog;
 import org.eclipse.egit.ui.internal.dialogs.MergeTargetSelectionDialog;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/MergeToolActionHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/MergeToolActionHandler.java
index 438504f..4f12b88 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/MergeToolActionHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/MergeToolActionHandler.java
@@ -24,8 +24,8 @@
 import org.eclipse.egit.core.internal.indexdiff.IndexDiffCache;
 import org.eclipse.egit.core.internal.indexdiff.IndexDiffCacheEntry;
 import org.eclipse.egit.core.internal.util.ResourceUtil;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.merge.GitMergeEditorInput;
 import org.eclipse.egit.ui.internal.merge.MergeModeDialog;
 import org.eclipse.jface.window.Window;
@@ -69,7 +69,7 @@
 		if (selectedRepoPaths.isEmpty())
 			return false;
 
-		IndexDiffCache cache = org.eclipse.egit.core.Activator.getDefault().getIndexDiffCache();
+		IndexDiffCache cache = org.eclipse.egit.core.internal.Activator.getDefault().getIndexDiffCache();
 		if (cache == null)
 			return false;
 
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/NoAssumeUnchangedActionHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/NoAssumeUnchangedActionHandler.java
index 74885e7..a8c5b43 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/NoAssumeUnchangedActionHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/NoAssumeUnchangedActionHandler.java
@@ -15,8 +15,8 @@
 import org.eclipse.core.commands.ExecutionException;
 import org.eclipse.core.resources.IResource;
 import org.eclipse.egit.core.internal.job.JobUtil;
-import org.eclipse.egit.core.op.AssumeUnchangedOperation;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.core.internal.op.AssumeUnchangedOperation;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 
 /**
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/PullFromUpstreamActionHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/PullFromUpstreamActionHandler.java
index 66b612b..68494e3 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/PullFromUpstreamActionHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/PullFromUpstreamActionHandler.java
@@ -17,7 +17,7 @@
 
 import org.eclipse.core.commands.ExecutionEvent;
 import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.pull.PullOperationUI;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.Repository;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/PushActionHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/PushActionHandler.java
index adcbb22..7eb4027 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/PushActionHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/PushActionHandler.java
@@ -15,7 +15,7 @@
 import org.eclipse.core.commands.ExecutionException;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.push.PushWizard;
 import org.eclipse.jface.dialogs.ErrorDialog;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/RebaseAction.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/RebaseAction.java
index e92aeea..8f9423d 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/RebaseAction.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/RebaseAction.java
@@ -12,7 +12,7 @@
 import org.eclipse.core.commands.ExecutionException;
 import org.eclipse.egit.core.internal.indexdiff.IndexDiffCache;
 import org.eclipse.egit.core.internal.indexdiff.IndexDiffCacheEntry;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIIcons;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.commands.shared.AbortRebaseCommand;
@@ -113,7 +113,7 @@
 	}
 
 	private boolean canContinue(Repository repo) {
-		IndexDiffCache diffCache = org.eclipse.egit.core.Activator.getDefault()
+		IndexDiffCache diffCache = org.eclipse.egit.core.internal.Activator.getDefault()
 				.getIndexDiffCache();
 		if (diffCache != null) {
 			IndexDiffCacheEntry entry = diffCache.getIndexDiffCacheEntry(repo);
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/RemoveFromIndexAction.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/RemoveFromIndexAction.java
index 05f67f1..e8a6003 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/RemoveFromIndexAction.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/RemoveFromIndexAction.java
@@ -10,7 +10,7 @@
 
 import static org.eclipse.egit.ui.internal.actions.ActionCommands.REMOVE_FROM_INDEX;
 
-import org.eclipse.egit.core.op.RemoveFromIndexOperation;
+import org.eclipse.egit.core.internal.op.RemoveFromIndexOperation;
 
 
 /**
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/RemoveFromIndexActionHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/RemoveFromIndexActionHandler.java
index d8531e1..40e2415 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/RemoveFromIndexActionHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/RemoveFromIndexActionHandler.java
@@ -18,10 +18,10 @@
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.egit.core.op.AddToIndexOperation;
-import org.eclipse.egit.core.op.RemoveFromIndexOperation;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.core.internal.op.AddToIndexOperation;
+import org.eclipse.egit.core.internal.op.RemoveFromIndexOperation;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 
 /**
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/RepositoryAction.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/RepositoryAction.java
index 3d8fb7e..ba7797c 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/RepositoryAction.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/RepositoryAction.java
@@ -19,7 +19,7 @@
 import org.eclipse.core.commands.NotHandledException;
 import org.eclipse.core.commands.common.NotDefinedException;
 import org.eclipse.core.expressions.IEvaluationContext;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.jface.action.IAction;
 import org.eclipse.jface.viewers.ISelection;
 import org.eclipse.ui.IObjectActionDelegate;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/RepositoryActionHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/RepositoryActionHandler.java
index d751ddc..80b1c61 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/RepositoryActionHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/RepositoryActionHandler.java
@@ -36,9 +36,9 @@
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.PlatformObject;
-import org.eclipse.egit.core.AdapterUtils;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.AdapterUtils;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.jface.text.TextSelection;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ResetAction.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ResetAction.java
index a26a431..83dd378 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ResetAction.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ResetAction.java
@@ -10,7 +10,7 @@
  *******************************************************************************/
 package org.eclipse.egit.ui.internal.actions;
 
-import org.eclipse.egit.core.op.ResetOperation;
+import org.eclipse.egit.core.internal.op.ResetOperation;
 
 /**
  * An action to reset the current branch to a specific revision.
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ResetActionHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ResetActionHandler.java
index b553863..0978631 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ResetActionHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ResetActionHandler.java
@@ -13,8 +13,8 @@
 import org.eclipse.core.commands.ExecutionEvent;
 import org.eclipse.core.commands.ExecutionException;
 import org.eclipse.egit.core.internal.job.JobUtil;
-import org.eclipse.egit.core.op.ResetOperation;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.core.internal.op.ResetOperation;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.dialogs.ResetTargetSelectionDialog;
 import org.eclipse.jface.dialogs.IDialogConstants;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ShowBlameActionHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ShowBlameActionHandler.java
index d60a2ab..f555793 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ShowBlameActionHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/ShowBlameActionHandler.java
@@ -16,8 +16,8 @@
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.resources.IStorage;
 import org.eclipse.egit.core.internal.job.JobUtil;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.blame.BlameOperation;
 import org.eclipse.jgit.lib.Repository;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/SimpleFetchActionHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/SimpleFetchActionHandler.java
index 1517546..c35294e 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/SimpleFetchActionHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/SimpleFetchActionHandler.java
@@ -10,8 +10,8 @@
 
 import org.eclipse.core.commands.ExecutionEvent;
 import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.fetch.FetchOperationUI;
 import org.eclipse.egit.ui.internal.fetch.SimpleConfigureFetchDialog;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/SimplePushActionHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/SimplePushActionHandler.java
index 4a738a5..70fd3e3 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/SimplePushActionHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/SimplePushActionHandler.java
@@ -10,8 +10,8 @@
 
 import org.eclipse.core.commands.ExecutionEvent;
 import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.push.PushOperationUI;
 import org.eclipse.egit.ui.internal.push.SimpleConfigurePushDialog;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/SwitchToMenu.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/SwitchToMenu.java
index 7b35b8e..bbc4f35 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/SwitchToMenu.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/SwitchToMenu.java
@@ -16,8 +16,8 @@
 
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.SWTUtils;
 import org.eclipse.egit.ui.internal.UIIcons;
 import org.eclipse.egit.ui.internal.UIText;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/SynchronizeWithMenu.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/SynchronizeWithMenu.java
index 5e8c7b2..a9d9a08 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/SynchronizeWithMenu.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/SynchronizeWithMenu.java
@@ -22,9 +22,9 @@
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeData;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.CommonUtils;
 import org.eclipse.egit.ui.internal.UIIcons;
 import org.eclipse.egit.ui.internal.UIText;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/SynchronizeWorkspaceActionHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/SynchronizeWorkspaceActionHandler.java
index 5328faa..6b09e6b 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/SynchronizeWorkspaceActionHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/SynchronizeWorkspaceActionHandler.java
@@ -8,7 +8,7 @@
  *******************************************************************************/
 package org.eclipse.egit.ui.internal.actions;
 
-import static org.eclipse.egit.core.synchronize.dto.GitSynchronizeData.BRANCH_NAME_PATTERN;
+import static org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeData.BRANCH_NAME_PATTERN;
 import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_BRANCH_SECTION;
 import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_MERGE;
 import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_REMOTE;
@@ -28,11 +28,11 @@
 import org.eclipse.core.resources.IContainer;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IResource;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeData;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeDataSet;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.synchronize.GitModelSynchronize;
 import org.eclipse.jgit.lib.Ref;
 import org.eclipse.jgit.lib.Repository;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/TagAction.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/TagAction.java
index ccfe4e4..4aa8d33 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/TagAction.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/TagAction.java
@@ -8,7 +8,7 @@
  *******************************************************************************/
 package org.eclipse.egit.ui.internal.actions;
 
-import org.eclipse.egit.core.op.TagOperation;
+import org.eclipse.egit.core.internal.op.TagOperation;
 
 /**
  * An action for creating tag.
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/TagActionHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/TagActionHandler.java
index 2456666..a304b1d 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/TagActionHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/TagActionHandler.java
@@ -17,9 +17,9 @@
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.egit.core.op.TagOperation;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.core.internal.op.TagOperation;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.decorators.GitLightweightDecorator;
 import org.eclipse.egit.ui.internal.dialogs.CreateTagDialog;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/UntrackAction.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/UntrackAction.java
index cc2b95d..7f0b879 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/UntrackAction.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/UntrackAction.java
@@ -8,7 +8,7 @@
  *******************************************************************************/
 package org.eclipse.egit.ui.internal.actions;
 
-import org.eclipse.egit.core.op.TagOperation;
+import org.eclipse.egit.core.internal.op.TagOperation;
 
 /**
  * An action for creating tag.
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/UntrackActionHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/UntrackActionHandler.java
index 2a6ae5d..414f155 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/UntrackActionHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/actions/UntrackActionHandler.java
@@ -16,8 +16,8 @@
 import org.eclipse.core.commands.ExecutionException;
 import org.eclipse.core.resources.IResource;
 import org.eclipse.egit.core.internal.job.JobUtil;
-import org.eclipse.egit.core.op.UntrackOperation;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.core.internal.op.UntrackOperation;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 
 /**
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/blame/BlameInformationControl.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/blame/BlameInformationControl.java
index fee9a38..5e70cc8 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/blame/BlameInformationControl.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/blame/BlameInformationControl.java
@@ -12,10 +12,10 @@
 
 import java.text.MessageFormat;
 
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
-import org.eclipse.egit.ui.UIUtils;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.egit.ui.internal.UIUtils;
 import org.eclipse.egit.ui.internal.commit.CommitEditor;
 import org.eclipse.egit.ui.internal.commit.RepositoryCommit;
 import org.eclipse.jface.layout.GridDataFactory;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/blame/BlameOperation.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/blame/BlameOperation.java
index 56b4993..1ac56dc 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/blame/BlameOperation.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/blame/BlameOperation.java
@@ -22,10 +22,10 @@
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.Platform;
 import org.eclipse.core.runtime.jobs.ISchedulingRule;
-import org.eclipse.egit.core.AdapterUtils;
-import org.eclipse.egit.core.op.IEGitOperation;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.core.internal.AdapterUtils;
+import org.eclipse.egit.core.internal.op.IEGitOperation;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.history.HistoryPageInput;
 import org.eclipse.jface.text.revisions.IRevisionRulerColumn;
 import org.eclipse.jface.text.revisions.IRevisionRulerColumnExtension;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/branch/BranchOperationUI.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/branch/BranchOperationUI.java
index c7c385a..01f3eaf 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/branch/BranchOperationUI.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/branch/BranchOperationUI.java
@@ -20,12 +20,12 @@
 import org.eclipse.core.runtime.jobs.IJobChangeEvent;
 import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.core.runtime.jobs.JobChangeAdapter;
-import org.eclipse.egit.core.op.BranchOperation;
-import org.eclipse.egit.core.op.IEGitOperation.PostExecuteTask;
-import org.eclipse.egit.core.op.IEGitOperation.PreExecuteTask;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.JobFamilies;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.core.internal.op.BranchOperation;
+import org.eclipse.egit.core.internal.op.IEGitOperation.PostExecuteTask;
+import org.eclipse.egit.core.internal.op.IEGitOperation.PreExecuteTask;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.JobFamilies;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.decorators.GitLightweightDecorator;
 import org.eclipse.egit.ui.internal.dialogs.AbstractBranchSelectionDialog;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/branch/BranchProjectTracker.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/branch/BranchProjectTracker.java
index 1cbf07a..001e707 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/branch/BranchProjectTracker.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/branch/BranchProjectTracker.java
@@ -26,9 +26,9 @@
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.egit.core.GitProvider;
+import org.eclipse.egit.core.internal.GitProvider;
 import org.eclipse.egit.core.internal.util.ProjectUtil;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.clone.ProjectRecord;
 import org.eclipse.egit.ui.internal.clone.ProjectUtils;
 import org.eclipse.jface.preference.IPreferenceStore;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/branch/BranchResultDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/branch/BranchResultDialog.java
index 4598c0b..cd9c6e3 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/branch/BranchResultDialog.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/branch/BranchResultDialog.java
@@ -16,10 +16,10 @@
 
 import org.eclipse.core.resources.IResource;
 import org.eclipse.egit.core.internal.job.JobUtil;
-import org.eclipse.egit.core.op.ResetOperation;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.JobFamilies;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.core.internal.op.ResetOperation;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.JobFamilies;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.commit.CommitUI;
 import org.eclipse.egit.ui.internal.dialogs.NonDeletedFilesDialog;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clean/CleanRepositoryPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clean/CleanRepositoryPage.java
index b64102c..06750f1 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clean/CleanRepositoryPage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clean/CleanRepositoryPage.java
@@ -18,7 +18,7 @@
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.SubProgressMonitor;
 import org.eclipse.egit.core.internal.util.ProjectUtil;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.layout.GridDataFactory;
 import org.eclipse.jface.operation.IRunnableWithProgress;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/AbstractGitCloneWizard.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/AbstractGitCloneWizard.java
index 82763bf..cff7afa 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/AbstractGitCloneWizard.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/AbstractGitCloneWizard.java
@@ -30,18 +30,18 @@
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.egit.core.RepositoryUtil;
+import org.eclipse.egit.core.internal.RepositoryUtil;
+import org.eclipse.egit.core.internal.op.CloneOperation;
+import org.eclipse.egit.core.internal.op.ConfigureFetchAfterCloneTask;
+import org.eclipse.egit.core.internal.op.ConfigurePushAfterCloneTask;
+import org.eclipse.egit.core.internal.op.SetRepositoryConfigPropertyTask;
+import org.eclipse.egit.core.internal.op.CloneOperation.PostCloneTask;
+import org.eclipse.egit.core.internal.securestorage.UserPasswordCredentials;
 import org.eclipse.egit.core.internal.util.ProjectUtil;
-import org.eclipse.egit.core.op.CloneOperation;
-import org.eclipse.egit.core.op.CloneOperation.PostCloneTask;
-import org.eclipse.egit.core.op.ConfigureFetchAfterCloneTask;
-import org.eclipse.egit.core.op.ConfigurePushAfterCloneTask;
-import org.eclipse.egit.core.op.SetRepositoryConfigPropertyTask;
-import org.eclipse.egit.core.securestorage.UserPasswordCredentials;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.JobFamilies;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.SecureStoreUtils;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.clone.GitCloneSourceProviderExtension.CloneSourceProvider;
 import org.eclipse.egit.ui.internal.components.RepositorySelection;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/CloneDestinationPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/CloneDestinationPage.java
index be7a965..8e1b8ff 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/CloneDestinationPage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/CloneDestinationPage.java
@@ -20,8 +20,8 @@
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.variables.IStringVariableManager;
 import org.eclipse.core.variables.VariablesPlugin;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.components.RepositorySelection;
 import org.eclipse.jface.dialogs.Dialog;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitCloneSourceProviderExtension.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitCloneSourceProviderExtension.java
index 4123938..4d7d031 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitCloneSourceProviderExtension.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitCloneSourceProviderExtension.java
@@ -17,7 +17,7 @@
 import org.eclipse.core.runtime.IConfigurationElement;
 import org.eclipse.core.runtime.IExtensionRegistry;
 import org.eclipse.core.runtime.Platform;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIIcons;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.provisional.wizards.IRepositorySearchResult;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitCloneWizard.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitCloneWizard.java
index 891c317..78e0854 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitCloneWizard.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitCloneWizard.java
@@ -17,7 +17,7 @@
 import java.io.IOException;
 import java.net.URISyntaxException;
 
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIIcons;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.components.RepositorySelectionPage;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitCreateProjectViaWizardWizard.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitCreateProjectViaWizardWizard.java
index 358f468..87e6d8c 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitCreateProjectViaWizardWizard.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitCreateProjectViaWizardWizard.java
@@ -27,8 +27,8 @@
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.core.op.ConnectProviderOperation;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.op.ConnectProviderOperation;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.operation.IRunnableWithProgress;
 import org.eclipse.jface.wizard.IWizardPage;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitImportWizard.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitImportWizard.java
index 52c0b4b..9b1e53a 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitImportWizard.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitImportWizard.java
@@ -30,8 +30,8 @@
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.core.op.ConnectProviderOperation;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.op.ConnectProviderOperation;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIIcons;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.clone.GitCloneSourceProviderExtension.CloneSourceProvider;
@@ -170,7 +170,7 @@
 			return existingRepo;
 		else
 			try {
-				return org.eclipse.egit.core.Activator
+				return org.eclipse.egit.core.internal.Activator
 						.getDefault()
 						.getRepositoryCache()
 						.lookupRepository(
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitProjectsImportPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitProjectsImportPage.java
index d2c90c4..55ec350 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitProjectsImportPage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitProjectsImportPage.java
@@ -28,7 +28,7 @@
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.egit.core.internal.util.ProjectUtil;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.CachedCheckboxTreeViewer;
 import org.eclipse.egit.ui.internal.FilteredCheckboxTree;
 import org.eclipse.egit.ui.internal.GitLabelProvider;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitSelectRepositoryPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitSelectRepositoryPage.java
index de3502b..b5cf2a8 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitSelectRepositoryPage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitSelectRepositoryPage.java
@@ -20,8 +20,8 @@
 
 import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener;
 import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;
-import org.eclipse.egit.core.RepositoryUtil;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.RepositoryUtil;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.repository.RepositoriesViewContentProvider;
 import org.eclipse.egit.ui.internal.repository.RepositoriesViewLabelProvider;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitSelectWizardPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitSelectWizardPage.java
index 92d685e..ff72fbb 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitSelectWizardPage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/GitSelectWizardPage.java
@@ -16,7 +16,7 @@
 
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.repository.RepositoriesViewContentProvider;
 import org.eclipse.egit.ui.internal.repository.RepositoriesViewLabelProvider;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/ProjectUtils.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/ProjectUtils.java
index ea2c405..5298cb7 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/ProjectUtils.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/ProjectUtils.java
@@ -24,7 +24,7 @@
 import org.eclipse.core.runtime.Path;
 import org.eclipse.core.runtime.Platform;
 import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.egit.core.op.ConnectProviderOperation;
+import org.eclipse.egit.core.internal.op.ConnectProviderOperation;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.ui.IWorkingSet;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/RepositoryLocationContentProvider.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/RepositoryLocationContentProvider.java
index 7f89251..f6ead57 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/RepositoryLocationContentProvider.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/RepositoryLocationContentProvider.java
@@ -16,7 +16,7 @@
 import java.util.Map;
 
 import org.eclipse.core.runtime.CoreException;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.clone.GitCloneSourceProviderExtension.CloneSourceProvider;
 import org.eclipse.egit.ui.internal.provisional.wizards.IRepositoryServerProvider;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/RepositoryLocationPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/RepositoryLocationPage.java
index 6c55dc3..bc33456 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/RepositoryLocationPage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/RepositoryLocationPage.java
@@ -15,7 +15,7 @@
 import java.util.Map;
 
 import org.eclipse.core.runtime.CoreException;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.clone.GitCloneSourceProviderExtension.CloneSourceProvider;
 import org.eclipse.egit.ui.internal.provisional.wizards.RepositoryServerInfo;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/SourceBranchPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/SourceBranchPage.java
index 291a7aa..dab0333 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/SourceBranchPage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/clone/SourceBranchPage.java
@@ -25,12 +25,12 @@
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.jobs.IJobChangeEvent;
 import org.eclipse.core.runtime.jobs.JobChangeAdapter;
-import org.eclipse.egit.core.op.ListRemoteOperation;
-import org.eclipse.egit.core.securestorage.UserPasswordCredentials;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.core.internal.op.ListRemoteOperation;
+import org.eclipse.egit.core.internal.securestorage.UserPasswordCredentials;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.CachedCheckboxTreeViewer;
 import org.eclipse.egit.ui.internal.FilteredCheckboxTree;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.components.RepositorySelection;
 import org.eclipse.egit.ui.internal.credentials.EGitCredentialsProvider;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commands/shared/AbstractRebaseCommandHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commands/shared/AbstractRebaseCommandHandler.java
index a9b324d..2c632b6 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commands/shared/AbstractRebaseCommandHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commands/shared/AbstractRebaseCommandHandler.java
@@ -20,7 +20,7 @@
 import org.eclipse.core.runtime.jobs.IJobChangeEvent;
 import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.core.runtime.jobs.JobChangeAdapter;
-import org.eclipse.egit.core.op.RebaseOperation;
+import org.eclipse.egit.core.internal.op.RebaseOperation;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.rebase.RebaseResultDialog;
 import org.eclipse.jface.dialogs.MessageDialog;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commands/shared/AbstractSharedCommandHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commands/shared/AbstractSharedCommandHandler.java
index cb61d86..49a9f17 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commands/shared/AbstractSharedCommandHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commands/shared/AbstractSharedCommandHandler.java
@@ -15,7 +15,7 @@
 import org.eclipse.core.commands.ExecutionEvent;
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.egit.core.project.RepositoryMapping;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
 import org.eclipse.egit.ui.internal.repository.tree.RefNode;
 import org.eclipse.egit.ui.internal.repository.tree.RepositoryTreeNode;
 import org.eclipse.egit.ui.internal.repository.tree.RepositoryTreeNodeType;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/CommitEditor.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/CommitEditor.java
index 965ab26..ccbcf53 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/CommitEditor.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/CommitEditor.java
@@ -15,7 +15,7 @@
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.commit.command.CheckoutHandler;
 import org.eclipse.egit.ui.internal.commit.command.CreateBranchHandler;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/CommitEditorInputFactory.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/CommitEditorInputFactory.java
index 7a6db58..3cab7a8 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/CommitEditorInputFactory.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/CommitEditorInputFactory.java
@@ -14,7 +14,7 @@
 import java.io.IOException;
 
 import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.egit.core.Activator;
+import org.eclipse.egit.core.internal.Activator;
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.revwalk.RevCommit;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/CommitEditorPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/CommitEditorPage.java
index 056c321..6b9b747 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/CommitEditorPage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/CommitEditorPage.java
@@ -28,11 +28,11 @@
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.jobs.ISchedulingRule;
 import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIUtils;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.GitLabelProvider;
 import org.eclipse.egit.ui.internal.UIIcons;
 import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.egit.ui.internal.UIUtils;
 import org.eclipse.egit.ui.internal.dialogs.SpellcheckableMessageArea;
 import org.eclipse.egit.ui.internal.history.CommitFileDiffViewer;
 import org.eclipse.egit.ui.internal.history.FileDiff;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/CommitHelper.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/CommitHelper.java
index 732b418..0bfc1bf 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/CommitHelper.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/CommitHelper.java
@@ -20,7 +20,7 @@
 import java.io.FileReader;
 import java.io.IOException;
 
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.ObjectId;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/CommitJob.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/CommitJob.java
index d7c57c4..0f496b2 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/CommitJob.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/CommitJob.java
@@ -18,11 +18,11 @@
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.egit.core.op.CommitOperation;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.JobFamilies;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.core.internal.op.CommitOperation;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.JobFamilies;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.decorators.GitLightweightDecorator;
 import org.eclipse.egit.ui.internal.dialogs.CommitMessageComponentStateManager;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/CommitMessageHistory.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/CommitMessageHistory.java
index f70e015..74bd1da 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/CommitMessageHistory.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/CommitMessageHistory.java
@@ -16,7 +16,7 @@
 import java.util.LinkedHashSet;
 import java.util.Set;
 
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.ui.IMemento;
 import org.eclipse.ui.WorkbenchException;
@@ -46,7 +46,7 @@
 		try {
 			memento = XMLMemento.createReadRoot(new StringReader(all));
 		} catch (WorkbenchException e) {
-			org.eclipse.egit.ui.Activator.logError(
+			org.eclipse.egit.ui.internal.Activator.logError(
 					"Error reading commit message history", e); //$NON-NLS-1$
 			return Collections.emptySet();
 		}
@@ -92,13 +92,13 @@
 					UIPreferences.COMMIT_DIALOG_HISTORY_MESSAGES,
 					writer.toString());
 		} catch (IOException e) {
-			org.eclipse.egit.ui.Activator.logError(
+			org.eclipse.egit.ui.internal.Activator.logError(
 					"Error writing commit message history", e); //$NON-NLS-1$
 		}
 	}
 
 	private static IPreferenceStore getPreferenceStore() {
-		return org.eclipse.egit.ui.Activator.getDefault().getPreferenceStore();
+		return org.eclipse.egit.ui.internal.Activator.getDefault().getPreferenceStore();
 	}
 
 	private static int getCommitHistorySize() {
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/CommitProposalProcessor.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/CommitProposalProcessor.java
index d426329..4f5cf17 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/CommitProposalProcessor.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/CommitProposalProcessor.java
@@ -18,8 +18,8 @@
 import java.util.TreeSet;
 
 import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.ui.UIUtils;
 import org.eclipse.egit.ui.internal.UIIcons;
+import org.eclipse.egit.ui.internal.UIUtils;
 import org.eclipse.jface.resource.JFaceResources;
 import org.eclipse.jface.resource.LocalResourceManager;
 import org.eclipse.jface.text.BadLocationException;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/CommitSelectionDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/CommitSelectionDialog.java
index c6b85b8..0c2ebbc 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/CommitSelectionDialog.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/CommitSelectionDialog.java
@@ -19,7 +19,7 @@
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.GitLabelProvider;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.search.CommitSearchPage;
@@ -173,7 +173,7 @@
 	}
 
 	private Repository[] getRepositories() {
-		return org.eclipse.egit.core.Activator.getDefault()
+		return org.eclipse.egit.core.internal.Activator.getDefault()
 				.getRepositoryCache().getAllRepositories();
 	}
 
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/CommitUI.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/CommitUI.java
index 7bb950f..20f2b2c 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/CommitUI.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/CommitUI.java
@@ -34,13 +34,13 @@
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.OperationCanceledException;
 import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.egit.core.EclipseGitProgressTransformer;
-import org.eclipse.egit.core.IteratorService;
-import org.eclipse.egit.core.op.CommitOperation;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIUtils;
+import org.eclipse.egit.core.internal.EclipseGitProgressTransformer;
+import org.eclipse.egit.core.internal.IteratorService;
+import org.eclipse.egit.core.internal.op.CommitOperation;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.egit.ui.internal.UIUtils;
 import org.eclipse.egit.ui.internal.dialogs.BasicConfigurationDialog;
 import org.eclipse.egit.ui.internal.dialogs.CommitDialog;
 import org.eclipse.jface.dialogs.IDialogConstants;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/DiffEditorPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/DiffEditorPage.java
index 841fc29..7abcf5d 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/DiffEditorPage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/DiffEditorPage.java
@@ -16,8 +16,8 @@
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.egit.ui.UIUtils;
 import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.egit.ui.internal.UIUtils;
 import org.eclipse.egit.ui.internal.history.FileDiff;
 import org.eclipse.jface.action.Action;
 import org.eclipse.jface.action.MenuManager;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/DiffViewer.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/DiffViewer.java
index 7b0a95e..e27e297 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/DiffViewer.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/DiffViewer.java
@@ -11,15 +11,15 @@
  *******************************************************************************/
 package org.eclipse.egit.ui.internal.commit;
 
-import static org.eclipse.egit.ui.UIPreferences.THEME_DiffAddBackgroundColor;
-import static org.eclipse.egit.ui.UIPreferences.THEME_DiffAddForegroundColor;
-import static org.eclipse.egit.ui.UIPreferences.THEME_DiffHunkBackgroundColor;
-import static org.eclipse.egit.ui.UIPreferences.THEME_DiffHunkForegroundColor;
-import static org.eclipse.egit.ui.UIPreferences.THEME_DiffRemoveBackgroundColor;
-import static org.eclipse.egit.ui.UIPreferences.THEME_DiffRemoveForegroundColor;
-import static org.eclipse.egit.ui.UIPreferences.THEME_DiffHeadlineBackgroundColor;
-import static org.eclipse.egit.ui.UIPreferences.THEME_DiffHeadlineForegroundColor;
-import static org.eclipse.egit.ui.UIPreferences.THEME_DiffHeadlineFont;
+import static org.eclipse.egit.ui.internal.UIPreferences.THEME_DiffAddBackgroundColor;
+import static org.eclipse.egit.ui.internal.UIPreferences.THEME_DiffAddForegroundColor;
+import static org.eclipse.egit.ui.internal.UIPreferences.THEME_DiffHeadlineBackgroundColor;
+import static org.eclipse.egit.ui.internal.UIPreferences.THEME_DiffHeadlineFont;
+import static org.eclipse.egit.ui.internal.UIPreferences.THEME_DiffHeadlineForegroundColor;
+import static org.eclipse.egit.ui.internal.UIPreferences.THEME_DiffHunkBackgroundColor;
+import static org.eclipse.egit.ui.internal.UIPreferences.THEME_DiffHunkForegroundColor;
+import static org.eclipse.egit.ui.internal.UIPreferences.THEME_DiffRemoveBackgroundColor;
+import static org.eclipse.egit.ui.internal.UIPreferences.THEME_DiffRemoveForegroundColor;
 
 import org.eclipse.egit.ui.internal.commit.DiffStyleRangeFormatter.DiffStyleRange;
 import org.eclipse.jface.preference.IPreferenceStore;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/HeaderText.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/HeaderText.java
index 8311479..f2d2def 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/HeaderText.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/HeaderText.java
@@ -14,8 +14,8 @@
 import java.lang.reflect.Field;
 import java.text.MessageFormat;
 
-import org.eclipse.egit.ui.UIUtils;
 import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.egit.ui.internal.UIUtils;
 import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.jface.text.Document;
 import org.eclipse.jface.text.TextViewer;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/RepositoryCommit.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/RepositoryCommit.java
index 86a6698..c2c61c6 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/RepositoryCommit.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/RepositoryCommit.java
@@ -21,7 +21,7 @@
 import org.eclipse.core.runtime.Assert;
 import org.eclipse.core.runtime.IAdaptable;
 import org.eclipse.core.runtime.Platform;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIIcons;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.history.FileDiff;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/RepositoryCommitNote.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/RepositoryCommitNote.java
index 091494c..40ff23c 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/RepositoryCommitNote.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/RepositoryCommitNote.java
@@ -14,7 +14,7 @@
 
 import org.eclipse.core.runtime.Assert;
 import org.eclipse.core.runtime.PlatformObject;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIIcons;
 import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.jgit.lib.Constants;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/command/CherryPickHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/command/CherryPickHandler.java
index fca9f4a..22e0670 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/command/CherryPickHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/command/CherryPickHandler.java
@@ -25,9 +25,9 @@
 import org.eclipse.core.runtime.MultiStatus;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.egit.core.op.CherryPickOperation;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.core.internal.op.CherryPickOperation;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.handler.SelectionHandler;
 import org.eclipse.jface.dialogs.MessageDialog;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/command/CreateTagHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/command/CreateTagHandler.java
index 838259c..da84525 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/command/CreateTagHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/command/CreateTagHandler.java
@@ -16,7 +16,7 @@
 import org.eclipse.core.commands.ExecutionException;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.egit.core.op.TagOperation;
+import org.eclipse.egit.core.internal.op.TagOperation;
 import org.eclipse.egit.ui.internal.commit.RepositoryCommit;
 import org.eclipse.egit.ui.internal.dialogs.CreateTagDialog;
 import org.eclipse.jface.window.Window;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/command/RevertHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/command/RevertHandler.java
index e370bfe..f80ae85 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/command/RevertHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/commit/command/RevertHandler.java
@@ -20,9 +20,9 @@
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.egit.core.op.RevertCommitOperation;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.core.internal.op.RevertCommitOperation;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.commit.RepositoryCommit;
 import org.eclipse.egit.ui.internal.dialogs.RevertFailureDialog;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RefContentAssistProvider.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RefContentAssistProvider.java
index b684ad3..96fcdb5 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RefContentAssistProvider.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RefContentAssistProvider.java
@@ -14,9 +14,9 @@
 import java.util.List;
 
 import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.egit.core.op.ListRemoteOperation;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.core.internal.op.ListRemoteOperation;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.dialogs.ProgressMonitorDialog;
 import org.eclipse.jface.operation.IRunnableWithProgress;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RefContentProposal.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RefContentProposal.java
index 712a780..488655e 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RefContentProposal.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RefContentProposal.java
@@ -11,7 +11,7 @@
 
 import java.io.IOException;
 
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.fieldassist.IContentProposal;
 import org.eclipse.jgit.lib.Constants;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RefSpecPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RefSpecPage.java
index c551d1e..97a0af4 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RefSpecPage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RefSpecPage.java
@@ -17,10 +17,10 @@
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
-import org.eclipse.egit.core.op.ListRemoteOperation;
-import org.eclipse.egit.core.securestorage.UserPasswordCredentials;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.core.internal.op.ListRemoteOperation;
+import org.eclipse.egit.core.internal.securestorage.UserPasswordCredentials;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.dialogs.Dialog;
 import org.eclipse.jface.dialogs.ErrorDialog;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RefSpecPanel.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RefSpecPanel.java
index 67b8170..9c10cf7 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RefSpecPanel.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RefSpecPanel.java
@@ -22,7 +22,7 @@
 import java.util.TreeSet;
 import java.util.regex.Pattern;
 
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIIcons;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.fieldassist.ComboContentAdapter;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RepositorySelectionPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RepositorySelectionPage.java
index 2e0fea8..55b1ddb 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RepositorySelectionPage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/RepositorySelectionPage.java
@@ -20,12 +20,12 @@
 import java.util.TreeMap;
 import java.util.regex.Pattern;
 
-import org.eclipse.egit.core.securestorage.UserPasswordCredentials;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
-import org.eclipse.egit.ui.UIUtils;
-import org.eclipse.egit.ui.UIUtils.IPreviousValueProposalHandler;
+import org.eclipse.egit.core.internal.securestorage.UserPasswordCredentials;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.egit.ui.internal.UIUtils;
+import org.eclipse.egit.ui.internal.UIUtils.IPreviousValueProposalHandler;
 import org.eclipse.egit.ui.internal.provisional.wizards.GitRepositoryInfo;
 import org.eclipse.egit.ui.internal.provisional.wizards.IRepositorySearchResult;
 import org.eclipse.jface.dialogs.Dialog;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/SimplePushSpecPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/SimplePushSpecPage.java
index af4f9c7..16af3cd 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/SimplePushSpecPage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/components/SimplePushSpecPage.java
@@ -12,9 +12,9 @@
 import java.util.List;
 
 import org.eclipse.core.runtime.IStatus;
-import org.eclipse.egit.ui.UIUtils;
-import org.eclipse.egit.ui.UIUtils.IRefListProvider;
 import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.egit.ui.internal.UIUtils;
+import org.eclipse.egit.ui.internal.UIUtils.IRefListProvider;
 import org.eclipse.jface.layout.GridDataFactory;
 import org.eclipse.jface.wizard.WizardPage;
 import org.eclipse.jgit.lib.BranchTrackingStatus;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/credentials/EGitCredentialsProvider.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/credentials/EGitCredentialsProvider.java
index 2243533..3836a14 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/credentials/EGitCredentialsProvider.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/credentials/EGitCredentialsProvider.java
@@ -13,8 +13,8 @@
 import java.text.MessageFormat;
 import java.util.concurrent.atomic.AtomicReference;
 
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.securestorage.UserPasswordCredentials;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.securestorage.UserPasswordCredentials;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.dialogs.CustomPromptDialog;
 import org.eclipse.equinox.security.storage.StorageException;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/credentials/LoginDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/credentials/LoginDialog.java
index 3cc8e75..2a8ff29 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/credentials/LoginDialog.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/credentials/LoginDialog.java
@@ -9,7 +9,7 @@
  *******************************************************************************/
 package org.eclipse.egit.ui.internal.credentials;
 
-import org.eclipse.egit.core.securestorage.UserPasswordCredentials;
+import org.eclipse.egit.core.internal.securestorage.UserPasswordCredentials;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.dialogs.Dialog;
 import org.eclipse.jface.layout.GridDataFactory;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/credentials/LoginService.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/credentials/LoginService.java
index d3c1a29..7028b70 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/credentials/LoginService.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/credentials/LoginService.java
@@ -10,8 +10,8 @@
 
 import java.io.IOException;
 
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.core.securestorage.UserPasswordCredentials;
+import org.eclipse.egit.core.internal.securestorage.UserPasswordCredentials;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.equinox.security.storage.StorageException;
 import org.eclipse.jface.window.Window;
@@ -72,7 +72,7 @@
 	private static void storeCredentials(URIish uri,
 			UserPasswordCredentials credentials) {
 		try {
-			org.eclipse.egit.core.Activator.getDefault().getSecureStore()
+			org.eclipse.egit.core.internal.Activator.getDefault().getSecureStore()
 					.putCredentials(uri, credentials);
 		} catch (StorageException e) {
 			Activator.handleError(UIText.LoginService_storingCredentialsFailed, e, true);
@@ -84,7 +84,7 @@
 	private static UserPasswordCredentials getCredentialsFromSecureStore(final URIish uri) {
 		UserPasswordCredentials credentials = null;
 		try {
-			credentials = org.eclipse.egit.core.Activator.getDefault().getSecureStore()
+			credentials = org.eclipse.egit.core.internal.Activator.getDefault().getSecureStore()
 					.getCredentials(uri);
 		} catch (StorageException e) {
 			Activator.logError(
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/DecoratableResourceAdapter.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/DecoratableResourceAdapter.java
index acb5650..e4778a5 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/DecoratableResourceAdapter.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/DecoratableResourceAdapter.java
@@ -24,7 +24,7 @@
 
 import org.eclipse.core.resources.IResource;
 import org.eclipse.egit.core.internal.indexdiff.IndexDiffData;
-import org.eclipse.egit.core.project.RepositoryMapping;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
 import org.eclipse.egit.ui.internal.trace.GitTraceLocation;
 import org.eclipse.jgit.lib.Repository;
 
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/DecoratableResourceHelper.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/DecoratableResourceHelper.java
index 2acdbc7..c3d3bde 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/DecoratableResourceHelper.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/DecoratableResourceHelper.java
@@ -12,7 +12,7 @@
 
 import java.io.IOException;
 
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.GitLabelProvider;
 import org.eclipse.jgit.lib.BranchTrackingStatus;
 import org.eclipse.jgit.lib.Repository;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/DecoratableResourceMapping.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/DecoratableResourceMapping.java
index d8d5444..4b6775a 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/DecoratableResourceMapping.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/DecoratableResourceMapping.java
@@ -19,7 +19,7 @@
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.resources.mapping.ResourceMapping;
 import org.eclipse.egit.core.internal.indexdiff.IndexDiffData;
-import org.eclipse.egit.core.project.RepositoryMapping;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.ui.IWorkingSet;
 
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/GitDocument.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/GitDocument.java
index c4d5c00..3e1e721 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/GitDocument.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/GitDocument.java
@@ -14,10 +14,10 @@
 import java.util.WeakHashMap;
 
 import org.eclipse.core.resources.IResource;
-import org.eclipse.egit.core.GitProvider;
 import org.eclipse.egit.core.internal.CompareCoreUtils;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.GitProvider;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.trace.GitTraceLocation;
 import org.eclipse.jface.text.Document;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/GitLightweightDecorator.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/GitLightweightDecorator.java
index 2977923..69a07a8 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/GitLightweightDecorator.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/GitLightweightDecorator.java
@@ -30,11 +30,11 @@
 import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.egit.core.internal.indexdiff.IndexDiffChangedListener;
 import org.eclipse.egit.core.internal.indexdiff.IndexDiffData;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
 import org.eclipse.egit.core.internal.util.ExceptionCollector;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIIcons;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.decorators.IDecoratableResource.Staged;
 import org.eclipse.jface.preference.IPreferenceStore;
@@ -99,7 +99,7 @@
 		PlatformUI.getWorkbench().getThemeManager().getCurrentTheme()
 				.addPropertyChangeListener(this);
 
-		org.eclipse.egit.core.Activator.getDefault().getIndexDiffCache().addIndexDiffChangedListener(this);
+		org.eclipse.egit.core.internal.Activator.getDefault().getIndexDiffCache().addIndexDiffChangedListener(this);
 		// This is an optimization to ensure that while decorating our fonts and colors are
 		// pre-created and decoration can occur without having to syncExec.
 		ensureFontAndColorsCreated(fonts, colors);
@@ -140,7 +140,7 @@
 				.removePropertyChangeListener(this);
 		TeamUI.removePropertyChangeListener(this);
 		Activator.removePropertyChangeListener(this);
-		org.eclipse.egit.core.Activator.getDefault().getIndexDiffCache().removeIndexDiffChangedListener(this);
+		org.eclipse.egit.core.internal.Activator.getDefault().getIndexDiffCache().removeIndexDiffChangedListener(this);
 	}
 
 	/**
@@ -211,7 +211,7 @@
 		if (mapping.getRepoRelativePath(resource) == null)
 			return null;
 
-		IndexDiffData indexDiffData = org.eclipse.egit.core.Activator
+		IndexDiffData indexDiffData = org.eclipse.egit.core.internal.Activator
 				.getDefault().getIndexDiffCache()
 				.getIndexDiffCacheEntry(mapping.getRepository()).getIndexDiff();
 
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/GitQuickDiffProvider.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/GitQuickDiffProvider.java
index fe2f036..cd97163 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/GitQuickDiffProvider.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/GitQuickDiffProvider.java
@@ -16,8 +16,8 @@
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.egit.core.GitProvider;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.GitProvider;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.trace.GitTraceLocation;
 import org.eclipse.jface.text.IDocument;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/ProblemLabelDecorator.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/ProblemLabelDecorator.java
index cf146c7..4033d19 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/ProblemLabelDecorator.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/ProblemLabelDecorator.java
@@ -19,7 +19,7 @@
 import org.eclipse.core.resources.IResourceChangeEvent;
 import org.eclipse.core.resources.IResourceChangeListener;
 import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.egit.core.AdapterUtils;
+import org.eclipse.egit.core.internal.AdapterUtils;
 import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.jface.resource.JFaceResources;
 import org.eclipse.jface.resource.LocalResourceManager;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/AbstractBranchSelectionDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/AbstractBranchSelectionDialog.java
index abe869a..6369361 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/AbstractBranchSelectionDialog.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/AbstractBranchSelectionDialog.java
@@ -21,8 +21,8 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIUtils;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.UIUtils;
 import org.eclipse.egit.ui.internal.repository.RepositoriesViewContentProvider;
 import org.eclipse.egit.ui.internal.repository.RepositoriesViewLabelProvider;
 import org.eclipse.egit.ui.internal.repository.tree.AdditionalRefsNode;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/BasicConfigurationDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/BasicConfigurationDialog.java
index 5b3656d..d5857c6 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/BasicConfigurationDialog.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/BasicConfigurationDialog.java
@@ -11,8 +11,8 @@
 
 import java.io.IOException;
 
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.preferences.GlobalConfigurationPreferencePage;
 import org.eclipse.jface.dialogs.TitleAreaDialog;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/BranchConfigurationDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/BranchConfigurationDialog.java
index 1bf6b51..765acc0 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/BranchConfigurationDialog.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/BranchConfigurationDialog.java
@@ -14,7 +14,7 @@
 
 import java.io.IOException;
 
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.dialogs.TitleAreaDialog;
 import org.eclipse.jface.layout.GridDataFactory;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/BranchRenameDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/BranchRenameDialog.java
index 1c7978c..4564fe5 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/BranchRenameDialog.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/BranchRenameDialog.java
@@ -9,8 +9,8 @@
 package org.eclipse.egit.ui.internal.dialogs;
 
 import org.eclipse.core.runtime.CoreException;
-import org.eclipse.egit.core.op.RenameBranchOperation;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.op.RenameBranchOperation;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.ValidationUtils;
 import org.eclipse.jface.dialogs.IInputValidator;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CheckoutDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CheckoutDialog.java
index bf23ad0..ac9375e 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CheckoutDialog.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CheckoutDialog.java
@@ -16,7 +16,7 @@
 import java.io.IOException;
 import java.util.Iterator;
 
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.CommonUtils;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.ValidationUtils;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CommitCombo.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CommitCombo.java
index 54ddf63..177e84e 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CommitCombo.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CommitCombo.java
@@ -13,8 +13,8 @@
 import java.util.regex.Pattern;
 
 import org.eclipse.core.runtime.Assert;
-import org.eclipse.egit.ui.UIUtils;
 import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.egit.ui.internal.UIUtils;
 import org.eclipse.jface.fieldassist.ComboContentAdapter;
 import org.eclipse.jface.fieldassist.ContentProposalAdapter;
 import org.eclipse.jface.fieldassist.IContentProposal;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CommitDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CommitDialog.java
index a4f36df..83f13c4 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CommitDialog.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CommitDialog.java
@@ -34,16 +34,16 @@
 import org.eclipse.core.runtime.Assert;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.AdaptableFileTreeIterator;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.AdaptableFileTreeIterator;
 import org.eclipse.egit.core.internal.util.ResourceUtil;
-import org.eclipse.egit.ui.UIPreferences;
-import org.eclipse.egit.ui.UIUtils;
 import org.eclipse.egit.ui.internal.CachedCheckboxTreeViewer;
 import org.eclipse.egit.ui.internal.CompareUtils;
 import org.eclipse.egit.ui.internal.FilteredCheckboxTree;
 import org.eclipse.egit.ui.internal.UIIcons;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.egit.ui.internal.UIUtils;
 import org.eclipse.egit.ui.internal.commit.CommitHelper;
 import org.eclipse.egit.ui.internal.commit.CommitMessageHistory;
 import org.eclipse.egit.ui.internal.commit.CommitProposalProcessor;
@@ -131,7 +131,7 @@
 public class CommitDialog extends TitleAreaDialog {
 
 	private static IPreferenceStore getPreferenceStore() {
-		return org.eclipse.egit.ui.Activator.getDefault().getPreferenceStore();
+		return org.eclipse.egit.ui.internal.Activator.getDefault().getPreferenceStore();
 	}
 
 	static class CommitFileContentProvider extends BaseWorkbenchContentProvider {
@@ -848,7 +848,7 @@
 		ColumnViewerToolTipSupport.enableFor(filesViewer);
 		filesViewer.setContentProvider(new CommitFileContentProvider());
 		filesViewer.setUseHashlookup(true);
-		IDialogSettings settings = org.eclipse.egit.ui.Activator.getDefault()
+		IDialogSettings settings = org.eclipse.egit.ui.internal.Activator.getDefault()
 				.getDialogSettings();
 		if (settings.get(SHOW_UNTRACKED_PREF) != null) {
 			// note, no matter how the dialog settings are, if
@@ -1180,7 +1180,7 @@
 		committer = commitMessageComponent.getCommitter();
 		createChangeId = changeIdItem.getSelection();
 
-		IDialogSettings settings = org.eclipse.egit.ui.Activator
+		IDialogSettings settings = org.eclipse.egit.ui.internal.Activator
 			.getDefault().getDialogSettings();
 		settings.put(SHOW_UNTRACKED_PREF, showUntracked);
 		CommitMessageHistory.saveCommitHistory(getCommitMessage());
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CommitMessageComponent.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CommitMessageComponent.java
index 57b1bf3..e423f6e 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CommitMessageComponent.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CommitMessageComponent.java
@@ -31,13 +31,13 @@
 import org.eclipse.core.runtime.IConfigurationElement;
 import org.eclipse.core.runtime.IExtensionRegistry;
 import org.eclipse.core.runtime.Platform;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.RevUtils;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.RevUtils;
 import org.eclipse.egit.ui.ICommitMessageProvider;
-import org.eclipse.egit.ui.UIPreferences;
-import org.eclipse.egit.ui.UIUtils;
-import org.eclipse.egit.ui.UIUtils.IPreviousValueProposalHandler;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.egit.ui.internal.UIUtils;
+import org.eclipse.egit.ui.internal.UIUtils.IPreviousValueProposalHandler;
 import org.eclipse.egit.ui.internal.commit.CommitHelper;
 import org.eclipse.egit.ui.internal.commit.CommitHelper.CommitInfo;
 import org.eclipse.jface.dialogs.IMessageProvider;
@@ -527,7 +527,7 @@
 		createChangeId = repository.getConfig().getBoolean(
 				ConfigConstants.CONFIG_GERRIT_SECTION,
 				ConfigConstants.CONFIG_KEY_CREATECHANGEID, false);
-		signedOff = org.eclipse.egit.ui.Activator.getDefault()
+		signedOff = org.eclipse.egit.ui.internal.Activator.getDefault()
 		.getPreferenceStore()
 		.getBoolean(UIPreferences.COMMIT_DIALOG_SIGNED_OFF_BY);
 	}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CommitMessageComponentStateManager.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CommitMessageComponentStateManager.java
index ea553aa..6855de7 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CommitMessageComponentStateManager.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CommitMessageComponentStateManager.java
@@ -8,7 +8,7 @@
  *******************************************************************************/
 package org.eclipse.egit.ui.internal.dialogs;
 
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.jface.dialogs.IDialogSettings;
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.Repository;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CompareTreeView.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CompareTreeView.java
index e72ddc3..99fb804 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CompareTreeView.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CompareTreeView.java
@@ -35,14 +35,12 @@
 import org.eclipse.core.runtime.Path;
 import org.eclipse.core.runtime.Platform;
 import org.eclipse.core.runtime.PlatformObject;
-import org.eclipse.egit.core.AdaptableFileTreeIterator;
+import org.eclipse.egit.core.internal.AdaptableFileTreeIterator;
 import org.eclipse.egit.core.internal.CompareCoreUtils;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
 import org.eclipse.egit.core.internal.storage.GitFileRevision;
 import org.eclipse.egit.core.internal.util.ResourceUtil;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
-import org.eclipse.egit.ui.UIUtils;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.CompareUtils;
 import org.eclipse.egit.ui.internal.EgitUiEditorUtils;
 import org.eclipse.egit.ui.internal.FileEditableRevision;
@@ -50,7 +48,9 @@
 import org.eclipse.egit.ui.internal.GitCompareFileRevisionEditorInput;
 import org.eclipse.egit.ui.internal.LocalFileRevision;
 import org.eclipse.egit.ui.internal.UIIcons;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.egit.ui.internal.UIUtils;
 import org.eclipse.egit.ui.internal.actions.BooleanPrefAction;
 import org.eclipse.egit.ui.internal.dialogs.CompareTreeView.PathNode.Type;
 import org.eclipse.jface.action.Action;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CreateTagDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CreateTagDialog.java
index 1bf873e..b428c2f 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CreateTagDialog.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/CreateTagDialog.java
@@ -25,12 +25,12 @@
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.JobFamilies;
-import org.eclipse.egit.ui.UIUtils;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.CompareUtils;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIIcons;
 import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.egit.ui.internal.UIUtils;
 import org.eclipse.egit.ui.internal.ValidationUtils;
 import org.eclipse.jface.dialogs.IDialogConstants;
 import org.eclipse.jface.dialogs.IInputValidator;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/DeleteBranchDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/DeleteBranchDialog.java
index 7e46473..3f1de5d 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/DeleteBranchDialog.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/DeleteBranchDialog.java
@@ -17,8 +17,8 @@
 import java.util.Set;
 
 import org.eclipse.core.runtime.CoreException;
-import org.eclipse.egit.core.op.DeleteBranchOperation;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.op.DeleteBranchOperation;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.repository.tree.RefNode;
 import org.eclipse.jface.dialogs.MessageDialog;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/FileTreeContentProvider.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/FileTreeContentProvider.java
index bbedf15..6468dc5 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/FileTreeContentProvider.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/FileTreeContentProvider.java
@@ -18,7 +18,7 @@
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.core.project.RepositoryMapping;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.viewers.ITreeContentProvider;
 import org.eclipse.jface.viewers.Viewer;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/GitTraceConfigurationDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/GitTraceConfigurationDialog.java
index e65eb3a..a836939 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/GitTraceConfigurationDialog.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/GitTraceConfigurationDialog.java
@@ -23,7 +23,7 @@
 import org.eclipse.core.filesystem.IFileStore;
 import org.eclipse.core.runtime.Path;
 import org.eclipse.core.runtime.Platform;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.dialogs.Dialog;
 import org.eclipse.jface.dialogs.IDialogConstants;
@@ -202,7 +202,7 @@
 
 	private static final PluginNode[] PLUGIN_LIST = new PluginNode[] {
 			new PluginNode(Activator.getPluginId()),
-			new PluginNode(org.eclipse.egit.core.Activator.getPluginId()) };
+			new PluginNode(org.eclipse.egit.core.internal.Activator.getPluginId()) };
 
 	private static final int APPLY_ID = 77;
 
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/MergeTargetSelectionDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/MergeTargetSelectionDialog.java
index 0f3bf7d..7c80942 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/MergeTargetSelectionDialog.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/MergeTargetSelectionDialog.java
@@ -17,7 +17,7 @@
 import java.io.IOException;
 import java.text.MessageFormat;
 
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.layout.GridDataFactory;
 import org.eclipse.jface.window.Window;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/NonDeletedFilesDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/NonDeletedFilesDialog.java
index c66c42a..70f2c60 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/NonDeletedFilesDialog.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/NonDeletedFilesDialog.java
@@ -18,7 +18,7 @@
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.CoreException;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.dialogs.IDialogConstants;
 import org.eclipse.jface.dialogs.MessageDialog;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/NonDeletedFilesTree.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/NonDeletedFilesTree.java
index d09c997..fc2fada 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/NonDeletedFilesTree.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/NonDeletedFilesTree.java
@@ -12,9 +12,9 @@
 
 import java.util.List;
 
-import org.eclipse.egit.ui.UIUtils;
 import org.eclipse.egit.ui.internal.UIIcons;
 import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.egit.ui.internal.UIUtils;
 import org.eclipse.egit.ui.internal.dialogs.FileTreeContentProvider.Mode;
 import org.eclipse.jface.layout.GridDataFactory;
 import org.eclipse.jface.layout.GridLayoutFactory;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/RenameBranchDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/RenameBranchDialog.java
index 0b598ea..926e43b 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/RenameBranchDialog.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/RenameBranchDialog.java
@@ -13,7 +13,7 @@
  *******************************************************************************/
 package org.eclipse.egit.ui.internal.dialogs;
 
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.ValidationUtils;
 import org.eclipse.jface.dialogs.InputDialog;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/ResetTargetSelectionDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/ResetTargetSelectionDialog.java
index 0617ffb..7a3860e 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/ResetTargetSelectionDialog.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/ResetTargetSelectionDialog.java
@@ -11,7 +11,7 @@
  *******************************************************************************/
 package org.eclipse.egit.ui.internal.dialogs;
 
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.jface.layout.GridDataFactory;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/SourceBranchFailureDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/SourceBranchFailureDialog.java
index 753398a..e09dcc6 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/SourceBranchFailureDialog.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/SourceBranchFailureDialog.java
@@ -8,8 +8,8 @@
  *******************************************************************************/
 package org.eclipse.egit.ui.internal.dialogs;
 
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.dialogs.IDialogConstants;
 import org.eclipse.jface.dialogs.MessageDialog;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/SpellcheckableMessageArea.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/SpellcheckableMessageArea.java
index ab6f08f..aed3f38 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/SpellcheckableMessageArea.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/dialogs/SpellcheckableMessageArea.java
@@ -24,10 +24,10 @@
 import org.eclipse.core.runtime.Assert;
 import org.eclipse.core.runtime.IAdaptable;
 import org.eclipse.egit.core.internal.Utils;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
-import org.eclipse.egit.ui.UIUtils;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.egit.ui.internal.UIUtils;
 import org.eclipse.jface.action.Action;
 import org.eclipse.jface.action.IAction;
 import org.eclipse.jface.action.IMenuListener;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/FetchDestinationPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/FetchDestinationPage.java
index ed281cb..90a2bcf 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/FetchDestinationPage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/FetchDestinationPage.java
@@ -12,10 +12,10 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIUtils;
-import org.eclipse.egit.ui.UIUtils.IRefListProvider;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.egit.ui.internal.UIUtils;
+import org.eclipse.egit.ui.internal.UIUtils.IRefListProvider;
 import org.eclipse.jface.dialogs.IMessageProvider;
 import org.eclipse.jface.layout.GridDataFactory;
 import org.eclipse.jface.wizard.WizardPage;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/FetchGerritChangePage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/FetchGerritChangePage.java
index 4daa917..3252f41 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/FetchGerritChangePage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/FetchGerritChangePage.java
@@ -25,13 +25,13 @@
 
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.egit.core.op.CreateLocalBranchOperation;
-import org.eclipse.egit.core.op.ListRemoteOperation;
-import org.eclipse.egit.core.op.TagOperation;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
-import org.eclipse.egit.ui.UIUtils;
+import org.eclipse.egit.core.internal.op.CreateLocalBranchOperation;
+import org.eclipse.egit.core.internal.op.ListRemoteOperation;
+import org.eclipse.egit.core.internal.op.TagOperation;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.egit.ui.internal.UIUtils;
 import org.eclipse.egit.ui.internal.branch.BranchOperationUI;
 import org.eclipse.egit.ui.internal.dialogs.CheckoutConflictDialog;
 import org.eclipse.jface.bindings.keys.KeyStroke;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/FetchOperationUI.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/FetchOperationUI.java
index ac3c530..bb2baf7 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/FetchOperationUI.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/FetchOperationUI.java
@@ -20,9 +20,9 @@
 import org.eclipse.core.runtime.jobs.IJobChangeEvent;
 import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.core.runtime.jobs.JobChangeAdapter;
-import org.eclipse.egit.core.op.FetchOperation;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.core.internal.op.FetchOperation;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.transport.CredentialsProvider;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/FetchResultDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/FetchResultDialog.java
index 3f83905..d8b2e79 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/FetchResultDialog.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/FetchResultDialog.java
@@ -9,9 +9,9 @@
  *******************************************************************************/
 package org.eclipse.egit.ui.internal.fetch;
 
-import org.eclipse.egit.core.op.FetchOperationResult;
-import org.eclipse.egit.ui.UIUtils;
+import org.eclipse.egit.core.internal.op.FetchOperationResult;
 import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.egit.ui.internal.UIUtils;
 import org.eclipse.jface.dialogs.Dialog;
 import org.eclipse.jface.dialogs.IDialogConstants;
 import org.eclipse.jface.dialogs.IDialogSettings;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/FetchResultTable.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/FetchResultTable.java
index 157df4b..3cd1648 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/FetchResultTable.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/FetchResultTable.java
@@ -14,10 +14,10 @@
 import java.util.List;
 import java.util.Map;
 
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIUtils;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIIcons;
 import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.egit.ui.internal.UIUtils;
 import org.eclipse.egit.ui.internal.WorkbenchStyledLabelProvider;
 import org.eclipse.egit.ui.internal.commit.CommitEditor;
 import org.eclipse.egit.ui.internal.commit.RepositoryCommit;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/FetchSourcePage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/FetchSourcePage.java
index d7454b8..05953da 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/FetchSourcePage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/FetchSourcePage.java
@@ -15,12 +15,12 @@
 import java.util.List;
 
 import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.egit.core.op.ListRemoteOperation;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
-import org.eclipse.egit.ui.UIUtils;
-import org.eclipse.egit.ui.UIUtils.IRefListProvider;
+import org.eclipse.egit.core.internal.op.ListRemoteOperation;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.egit.ui.internal.UIUtils;
+import org.eclipse.egit.ui.internal.UIUtils.IRefListProvider;
 import org.eclipse.jface.dialogs.IMessageProvider;
 import org.eclipse.jface.dialogs.ProgressMonitorDialog;
 import org.eclipse.jface.layout.GridDataFactory;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/FetchWizard.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/FetchWizard.java
index 7c11ad0..8f30626 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/FetchWizard.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/FetchWizard.java
@@ -15,11 +15,11 @@
 
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
-import org.eclipse.egit.core.securestorage.UserPasswordCredentials;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.core.internal.securestorage.UserPasswordCredentials;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.SecureStoreUtils;
 import org.eclipse.egit.ui.internal.UIIcons;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.components.RefSpecPage;
 import org.eclipse.egit.ui.internal.components.RepositorySelection;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/SimpleConfigureFetchDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/SimpleConfigureFetchDialog.java
index d3e2270..7f36026 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/SimpleConfigureFetchDialog.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/fetch/SimpleConfigureFetchDialog.java
@@ -17,8 +17,8 @@
 
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.push.RefSpecDialog;
 import org.eclipse.egit.ui.internal.push.RefSpecWizard;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/gerrit/ConfigureGerritWizard.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/gerrit/ConfigureGerritWizard.java
index 140fbb4..fa89ffa 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/gerrit/ConfigureGerritWizard.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/gerrit/ConfigureGerritWizard.java
@@ -13,7 +13,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIIcons;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.wizard.Wizard;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/gerrit/GerritConfigurationPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/gerrit/GerritConfigurationPage.java
index 5a46b46..7e6bf76 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/gerrit/GerritConfigurationPage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/gerrit/GerritConfigurationPage.java
@@ -19,10 +19,10 @@
 import java.util.regex.Pattern;
 import java.util.regex.PatternSyntaxException;
 
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIUtils;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.SWTUtils;
 import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.egit.ui.internal.UIUtils;
 import org.eclipse.egit.ui.internal.components.RepositorySelectionPage.Protocol;
 import org.eclipse.jface.bindings.keys.KeyStroke;
 import org.eclipse.jface.bindings.keys.ParseException;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/handler/SelectionHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/handler/SelectionHandler.java
index f9b2ab9..6d23bfb 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/handler/SelectionHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/handler/SelectionHandler.java
@@ -16,7 +16,7 @@
 import org.eclipse.core.commands.AbstractHandler;
 import org.eclipse.core.commands.ExecutionEvent;
 import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.egit.core.AdapterUtils;
+import org.eclipse.egit.core.internal.AdapterUtils;
 import org.eclipse.jface.viewers.ISelection;
 import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.jface.viewers.StructuredSelection;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitFileDiffViewer.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitFileDiffViewer.java
index 2b0d6fa..0c49daa 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitFileDiffViewer.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitFileDiffViewer.java
@@ -27,15 +27,15 @@
 import org.eclipse.core.runtime.Path;
 import org.eclipse.egit.core.internal.job.JobUtil;
 import org.eclipse.egit.core.internal.util.ResourceUtil;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.JobFamilies;
-import org.eclipse.egit.ui.UIPreferences;
-import org.eclipse.egit.ui.UIUtils;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.CompareUtils;
 import org.eclipse.egit.ui.internal.EgitUiEditorUtils;
 import org.eclipse.egit.ui.internal.GitCompareFileRevisionEditorInput;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIIcons;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.egit.ui.internal.UIUtils;
 import org.eclipse.egit.ui.internal.blame.BlameOperation;
 import org.eclipse.egit.ui.internal.synchronize.GitModelSynchronize;
 import org.eclipse.jface.action.Action;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitGraphTable.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitGraphTable.java
index 399bdc4..2c10c2d 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitGraphTable.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitGraphTable.java
@@ -31,13 +31,13 @@
 import org.eclipse.core.commands.common.NotDefinedException;
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.runtime.CoreException;
-import org.eclipse.egit.core.op.CreatePatchOperation;
-import org.eclipse.egit.core.op.CreatePatchOperation.DiffHeaderFormat;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
-import org.eclipse.egit.ui.UIUtils;
+import org.eclipse.egit.core.internal.op.CreatePatchOperation;
+import org.eclipse.egit.core.internal.op.CreatePatchOperation.DiffHeaderFormat;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIIcons;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.egit.ui.internal.UIUtils;
 import org.eclipse.egit.ui.internal.history.SWTCommitList.SWTLane;
 import org.eclipse.egit.ui.internal.history.command.HistoryViewCommands;
 import org.eclipse.egit.ui.internal.trace.GitTraceLocation;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitInfoBuilder.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitInfoBuilder.java
index 309cf57..9aed091 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitInfoBuilder.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitInfoBuilder.java
@@ -32,8 +32,8 @@
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.OperationCanceledException;
 import org.eclipse.egit.core.internal.CompareCoreUtils;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.history.CommitMessageViewer.ObjectLink;
 import org.eclipse.egit.ui.internal.trace.GitTraceLocation;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitMessageViewer.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitMessageViewer.java
index f44e5a4..79cfe50 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitMessageViewer.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitMessageViewer.java
@@ -20,10 +20,10 @@
 import org.eclipse.core.runtime.jobs.IJobChangeEvent;
 import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.core.runtime.jobs.JobChangeAdapter;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
-import org.eclipse.egit.ui.UIUtils;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.egit.ui.internal.UIUtils;
 import org.eclipse.egit.ui.internal.actions.BooleanPrefAction;
 import org.eclipse.jface.action.Action;
 import org.eclipse.jface.action.IAction;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitSelectionDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitSelectionDialog.java
index e3cb751..3b9592e 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitSelectionDialog.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitSelectionDialog.java
@@ -16,11 +16,11 @@
 
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
-import org.eclipse.egit.ui.UIUtils;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.egit.ui.internal.UIUtils;
 import org.eclipse.jface.dialogs.IMessageProvider;
 import org.eclipse.jface.dialogs.TitleAreaDialog;
 import org.eclipse.jface.layout.GridDataFactory;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/FileDiff.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/FileDiff.java
index 1f12934..add5524 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/FileDiff.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/FileDiff.java
@@ -21,9 +21,9 @@
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.ui.UIUtils;
 import org.eclipse.egit.ui.internal.DecorationOverlayDescriptor;
 import org.eclipse.egit.ui.internal.UIIcons;
+import org.eclipse.egit.ui.internal.UIUtils;
 import org.eclipse.jface.resource.ImageDescriptor;
 import org.eclipse.jface.viewers.IDecoration;
 import org.eclipse.jgit.diff.DiffEntry;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/FileDiffContentProvider.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/FileDiffContentProvider.java
index 33a4869..bc16992 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/FileDiffContentProvider.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/FileDiffContentProvider.java
@@ -12,7 +12,7 @@
 import java.io.IOException;
 import java.util.Set;
 
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.viewers.IStructuredContentProvider;
 import org.eclipse.jface.viewers.Viewer;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/FindToolbar.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/FindToolbar.java
index 65f5143..a164af7 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/FindToolbar.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/FindToolbar.java
@@ -15,9 +15,9 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIIcons;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.preference.IPersistentPreferenceStore;
 import org.eclipse.jgit.revwalk.RevFlag;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/FindToolbarThread.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/FindToolbarThread.java
index f4ec52a..7541d82 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/FindToolbarThread.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/FindToolbarThread.java
@@ -10,7 +10,7 @@
 
 import java.io.IOException;
 
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 
 /**
  * This class executes the search function for the find toolbar. Only one thread
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/FormatJob.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/FormatJob.java
index a8d8bfd..d89e8a5 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/FormatJob.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/FormatJob.java
@@ -20,8 +20,8 @@
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jgit.lib.Ref;
 import org.eclipse.jgit.lib.Repository;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GenerateHistoryJob.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GenerateHistoryJob.java
index b4f60e7..ecf2720 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GenerateHistoryJob.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GenerateHistoryJob.java
@@ -18,9 +18,9 @@
 import org.eclipse.core.runtime.jobs.IJobChangeEvent;
 import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.core.runtime.jobs.JobChangeAdapter;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.JobFamilies;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.JobFamilies;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.trace.GitTraceLocation;
 import org.eclipse.jface.resource.ResourceManager;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitCreatePatchWizard.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitCreatePatchWizard.java
index 56c9bb3..06707e1 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitCreatePatchWizard.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitCreatePatchWizard.java
@@ -30,10 +30,10 @@
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.egit.core.op.CreatePatchOperation;
-import org.eclipse.egit.core.op.CreatePatchOperation.DiffHeaderFormat;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.op.CreatePatchOperation;
+import org.eclipse.egit.core.internal.op.CreatePatchOperation.DiffHeaderFormat;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIIcons;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.dialogs.Dialog;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitHistoryPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitHistoryPage.java
index 3ba6788..693fa01 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitHistoryPage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitHistoryPage.java
@@ -30,14 +30,14 @@
 import org.eclipse.core.runtime.Path;
 import org.eclipse.core.runtime.jobs.ISchedulingRule;
 import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.egit.core.AdapterUtils;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
-import org.eclipse.egit.ui.UIUtils;
+import org.eclipse.egit.core.internal.AdapterUtils;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.CompareUtils;
 import org.eclipse.egit.ui.internal.UIIcons;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.egit.ui.internal.UIUtils;
 import org.eclipse.egit.ui.internal.repository.tree.AdditionalRefNode;
 import org.eclipse.egit.ui.internal.repository.tree.FileNode;
 import org.eclipse.egit.ui.internal.repository.tree.FolderNode;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GraphLabelProvider.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GraphLabelProvider.java
index d31452b..d4f3b05 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GraphLabelProvider.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GraphLabelProvider.java
@@ -14,7 +14,7 @@
 
 import java.io.IOException;
 
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.dialogs.CommitLabelProvider;
 
 /**
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/HistoryPageInput.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/HistoryPageInput.java
index 2e0e985..0deba0c 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/HistoryPageInput.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/HistoryPageInput.java
@@ -16,7 +16,7 @@
 import java.util.List;
 
 import org.eclipse.core.resources.IResource;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.Ref;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/LocationPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/LocationPage.java
index 7a60c5a..f5e6b5d 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/LocationPage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/LocationPage.java
@@ -26,7 +26,7 @@
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.core.op.CreatePatchOperation;
+import org.eclipse.egit.core.internal.op.CreatePatchOperation;
 import org.eclipse.egit.ui.internal.UIIcons;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.dialogs.Dialog;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/SWTPlotRenderer.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/SWTPlotRenderer.java
index c13cddf..ddf1100 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/SWTPlotRenderer.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/SWTPlotRenderer.java
@@ -14,8 +14,8 @@
 import java.util.HashMap;
 import java.util.Map;
 
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.history.SWTCommitList.SWTLane;
 import org.eclipse.jface.resource.ResourceManager;
 import org.eclipse.jgit.lib.Constants;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/AbstractHistoryCommandHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/AbstractHistoryCommandHandler.java
index c0e62c4..404dac8 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/AbstractHistoryCommandHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/AbstractHistoryCommandHandler.java
@@ -25,8 +25,8 @@
 import org.eclipse.core.runtime.IAdaptable;
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.core.AdapterUtils;
-import org.eclipse.egit.core.project.RepositoryMapping;
+import org.eclipse.egit.core.internal.AdapterUtils;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
 import org.eclipse.egit.ui.internal.CompareUtils;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.history.GitHistoryPage;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/CompareVersionsHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/CompareVersionsHandler.java
index 22a12aa..f1d4a0a 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/CompareVersionsHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/CompareVersionsHandler.java
@@ -17,7 +17,7 @@
 import org.eclipse.core.commands.ExecutionException;
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IResource;
-import org.eclipse.egit.core.project.RepositoryMapping;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
 import org.eclipse.egit.ui.internal.CompareUtils;
 import org.eclipse.egit.ui.internal.GitCompareFileRevisionEditorInput;
 import org.eclipse.egit.ui.internal.history.GitHistoryPage;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/CompareVersionsInTreeHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/CompareVersionsInTreeHandler.java
index 57c1bda..ae70a7d 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/CompareVersionsInTreeHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/CompareVersionsInTreeHandler.java
@@ -17,8 +17,8 @@
 import org.eclipse.core.commands.ExecutionException;
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IResource;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.CompareUtils;
 import org.eclipse.egit.ui.internal.GitCompareFileRevisionEditorInput;
 import org.eclipse.egit.ui.internal.dialogs.CompareTreeView;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/CompareWithWorkingTreeHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/CompareWithWorkingTreeHandler.java
index 95326af..b9a2e30 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/CompareWithWorkingTreeHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/CompareWithWorkingTreeHandler.java
@@ -16,7 +16,7 @@
 import org.eclipse.core.commands.ExecutionEvent;
 import org.eclipse.core.commands.ExecutionException;
 import org.eclipse.core.resources.IFile;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.CompareUtils;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.history.GitHistoryPage;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/CreateTagOnCommitHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/CreateTagOnCommitHandler.java
index a466257..c0e977a 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/CreateTagOnCommitHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/CreateTagOnCommitHandler.java
@@ -12,7 +12,7 @@
 import org.eclipse.core.commands.ExecutionException;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.egit.core.op.TagOperation;
+import org.eclipse.egit.core.internal.op.TagOperation;
 import org.eclipse.egit.ui.internal.dialogs.CreateTagDialog;
 import org.eclipse.egit.ui.internal.history.GitHistoryPage;
 import org.eclipse.jface.viewers.IStructuredSelection;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/DeleteBranchOnCommitHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/DeleteBranchOnCommitHandler.java
index 50cc851..727e1f8 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/DeleteBranchOnCommitHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/DeleteBranchOnCommitHandler.java
@@ -17,8 +17,8 @@
 import org.eclipse.core.commands.ExecutionException;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.egit.core.op.DeleteBranchOperation;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.op.DeleteBranchOperation;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.dialogs.BranchSelectionDialog;
 import org.eclipse.egit.ui.internal.dialogs.UnmergedBranchDialog;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/MergeHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/MergeHandler.java
index 3c81d65..98ea5b5 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/MergeHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/MergeHandler.java
@@ -25,8 +25,8 @@
 import org.eclipse.core.runtime.jobs.IJobChangeEvent;
 import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.core.runtime.jobs.JobChangeAdapter;
-import org.eclipse.egit.core.op.MergeOperation;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.op.MergeOperation;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.dialogs.BranchSelectionDialog;
 import org.eclipse.egit.ui.internal.merge.MergeResultDialog;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/OpenInCommitViewerHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/OpenInCommitViewerHandler.java
index 9281a58..2858d57 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/OpenInCommitViewerHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/OpenInCommitViewerHandler.java
@@ -15,7 +15,7 @@
 
 import org.eclipse.core.commands.ExecutionEvent;
 import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.commit.CommitEditor;
 import org.eclipse.egit.ui.internal.commit.RepositoryCommit;
 import org.eclipse.jgit.lib.Repository;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/OpenInTextEditorHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/OpenInTextEditorHandler.java
index ca484c8..8bbbf42 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/OpenInTextEditorHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/OpenInTextEditorHandler.java
@@ -18,8 +18,8 @@
 import org.eclipse.core.commands.ExecutionException;
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.runtime.CoreException;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.CompareUtils;
 import org.eclipse.egit.ui.internal.EgitUiEditorUtils;
 import org.eclipse.egit.ui.internal.UIText;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/PushCommitHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/PushCommitHandler.java
index c0c68ba..44c7226 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/PushCommitHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/PushCommitHandler.java
@@ -10,7 +10,7 @@
 
 import org.eclipse.core.commands.ExecutionEvent;
 import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.history.GitHistoryPage;
 import org.eclipse.egit.ui.internal.push.SimplePushRefWizard;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/ResetHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/ResetHandler.java
index 6ac1eb5..b621eb7 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/ResetHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/ResetHandler.java
@@ -11,8 +11,8 @@
 import org.eclipse.core.commands.ExecutionEvent;
 import org.eclipse.core.commands.ExecutionException;
 import org.eclipse.egit.core.internal.job.JobUtil;
-import org.eclipse.egit.core.op.ResetOperation;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.core.internal.op.ResetOperation;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.jgit.api.ResetCommand.ResetType;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/ShowBlameHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/ShowBlameHandler.java
index b25f82d..c4ee630 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/ShowBlameHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/ShowBlameHandler.java
@@ -20,10 +20,10 @@
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.egit.core.internal.job.JobUtil;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.CompareUtils;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.blame.BlameOperation;
 import org.eclipse.egit.ui.internal.history.GitHistoryPage;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/ShowVersionsHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/ShowVersionsHandler.java
index 003434b..42be0d4 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/ShowVersionsHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/command/ShowVersionsHandler.java
@@ -19,8 +19,8 @@
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.CompareUtils;
 import org.eclipse.egit.ui.internal.EgitUiEditorUtils;
 import org.eclipse.egit.ui.internal.UIText;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/merge/GitCompareEditorInput.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/merge/GitCompareEditorInput.java
index 7c2b4ad..07b5362 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/merge/GitCompareEditorInput.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/merge/GitCompareEditorInput.java
@@ -28,11 +28,11 @@
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.core.AdaptableFileTreeIterator;
+import org.eclipse.egit.core.internal.AdaptableFileTreeIterator;
 import org.eclipse.egit.core.internal.CompareCoreUtils;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
 import org.eclipse.egit.core.internal.storage.GitFileRevision;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.FileRevisionTypedElement;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.dialogs.CompareTreeView;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/merge/GitMergeEditorInput.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/merge/GitMergeEditorInput.java
index a3ce8e7..29bb6a1 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/merge/GitMergeEditorInput.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/merge/GitMergeEditorInput.java
@@ -29,9 +29,9 @@
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.Path;
 import org.eclipse.egit.core.internal.CompareCoreUtils;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
 import org.eclipse.egit.core.internal.storage.GitFileRevision;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.CompareUtils;
 import org.eclipse.egit.ui.internal.FileEditableRevision;
 import org.eclipse.egit.ui.internal.FileRevisionTypedElement;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/merge/MergeModeDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/merge/MergeModeDialog.java
index b8038b1..90ed59a 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/merge/MergeModeDialog.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/merge/MergeModeDialog.java
@@ -8,8 +8,8 @@
  *******************************************************************************/
 package org.eclipse.egit.ui.internal.merge;
 
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.dialogs.Dialog;
 import org.eclipse.jface.preference.IPreferenceStore;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/merge/MergeResultDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/merge/MergeResultDialog.java
index 44f9741..3b47b9f 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/merge/MergeResultDialog.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/merge/MergeResultDialog.java
@@ -15,9 +15,9 @@
 import java.util.Map.Entry;
 import java.util.Set;
 
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIUtils;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.egit.ui.internal.UIUtils;
 import org.eclipse.egit.ui.internal.commit.CommitEditor;
 import org.eclipse.egit.ui.internal.commit.RepositoryCommit;
 import org.eclipse.egit.ui.internal.dialogs.CheckoutConflictDialog;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/operations/DeletePathsOperationUI.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/operations/DeletePathsOperationUI.java
index 20fb830..852c04f 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/operations/DeletePathsOperationUI.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/operations/DeletePathsOperationUI.java
@@ -15,9 +15,9 @@
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IPath;
+import org.eclipse.egit.core.internal.op.DeletePathsOperation;
 import org.eclipse.egit.core.internal.util.ResourceUtil;
-import org.eclipse.egit.core.op.DeletePathsOperation;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.jface.viewers.IStructuredSelection;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/operations/GitScopeOperation.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/operations/GitScopeOperation.java
index d42153c..18a7453 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/operations/GitScopeOperation.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/operations/GitScopeOperation.java
@@ -19,8 +19,8 @@
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.resources.mapping.ResourceTraversal;
 import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jgit.api.Git;
 import org.eclipse.jgit.api.Status;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/operations/GitScopeUtil.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/operations/GitScopeUtil.java
index 0485a65..585f045 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/operations/GitScopeUtil.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/operations/GitScopeUtil.java
@@ -22,9 +22,9 @@
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.Platform;
 import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.egit.core.synchronize.GitResourceVariantTreeSubscriber;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.synchronize.GitResourceVariantTreeSubscriber;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeDataSet;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.operation.IRunnableWithProgress;
 import org.eclipse.team.core.subscribers.Subscriber;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/operations/IgnoreOperationUI.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/operations/IgnoreOperationUI.java
index 80c2123..4dc4ee5 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/operations/IgnoreOperationUI.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/operations/IgnoreOperationUI.java
@@ -19,9 +19,9 @@
 import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.egit.core.internal.indexdiff.IndexDiffCache;
 import org.eclipse.egit.core.internal.indexdiff.IndexDiffCacheEntry;
+import org.eclipse.egit.core.internal.op.IgnoreOperation;
 import org.eclipse.egit.core.internal.util.ResourceUtil;
-import org.eclipse.egit.core.op.IgnoreOperation;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.decorators.GitLightweightDecorator;
 import org.eclipse.jgit.lib.Repository;
@@ -73,7 +73,7 @@
 		Map<Repository, Collection<String>> pathsByRepository =
 				ResourceUtil.splitPathsByRepository(paths);
 		for (Repository repository : pathsByRepository.keySet()) {
-			IndexDiffCache cache = org.eclipse.egit.core.Activator.getDefault().getIndexDiffCache();
+			IndexDiffCache cache = org.eclipse.egit.core.internal.Activator.getDefault().getIndexDiffCache();
 			IndexDiffCacheEntry entry = cache.getIndexDiffCacheEntry(repository);
 			if (entry != null)
 				entry.refresh();
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/patch/PatchOperationUI.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/patch/PatchOperationUI.java
index 6d24158..e20cd29 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/patch/PatchOperationUI.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/patch/PatchOperationUI.java
@@ -16,7 +16,7 @@
 import org.eclipse.core.resources.IResource;
 import org.eclipse.egit.core.internal.indexdiff.IndexDiffCache;
 import org.eclipse.egit.core.internal.indexdiff.IndexDiffData;
-import org.eclipse.egit.core.op.CreatePatchOperation;
+import org.eclipse.egit.core.internal.op.CreatePatchOperation;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.history.GitCreatePatchWizard;
 import org.eclipse.jface.dialogs.MessageDialog;
@@ -107,7 +107,7 @@
 	}
 
 	private boolean isWorkingTreeClean() {
-		IndexDiffCache diffCache = org.eclipse.egit.core.Activator.getDefault()
+		IndexDiffCache diffCache = org.eclipse.egit.core.internal.Activator.getDefault()
 				.getIndexDiffCache();
 		if (diffCache != null) {
 			IndexDiffData diffData = diffCache.getIndexDiffCacheEntry(
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/CommitDialogPreferencePage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/CommitDialogPreferencePage.java
index 5865f7f..2ea66ce 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/CommitDialogPreferencePage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/CommitDialogPreferencePage.java
@@ -8,8 +8,8 @@
  *******************************************************************************/
 package org.eclipse.egit.ui.internal.preferences;
 
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.layout.GridDataFactory;
 import org.eclipse.jface.preference.BooleanFieldEditor;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/ConfigurationEditorComponent.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/ConfigurationEditorComponent.java
index 016c309..806668e 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/ConfigurationEditorComponent.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/ConfigurationEditorComponent.java
@@ -25,8 +25,8 @@
 import org.eclipse.core.runtime.Path;
 import org.eclipse.core.runtime.preferences.IEclipsePreferences;
 import org.eclipse.core.runtime.preferences.InstanceScope;
-import org.eclipse.egit.core.GitCorePreferences;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.GitCorePreferences;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.jface.layout.GridDataFactory;
@@ -166,7 +166,7 @@
 		if (changeablePath) {
 			try {
 				IEclipsePreferences node = InstanceScope.INSTANCE
-						.getNode(org.eclipse.egit.core.Activator.getPluginId());
+						.getNode(org.eclipse.egit.core.internal.Activator.getPluginId());
 				node.remove(GitCorePreferences.core_gitPrefix);
 				node.flush();
 				// Create a temporary FS instance to compute the Git prefix
@@ -243,7 +243,7 @@
 							location.setText(file);
 							try {
 								IEclipsePreferences node = InstanceScope.INSTANCE
-										.getNode(org.eclipse.egit.core.Activator
+										.getNode(org.eclipse.egit.core.internal.Activator
 												.getPluginId());
 								node.put(GitCorePreferences.core_gitPrefix,
 										file);
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/DialogsPreferencePage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/DialogsPreferencePage.java
index d065ac1..9a4a984 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/DialogsPreferencePage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/DialogsPreferencePage.java
@@ -9,8 +9,8 @@
  *******************************************************************************/
 package org.eclipse.egit.ui.internal.preferences;
 
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.layout.GridDataFactory;
 import org.eclipse.jface.preference.BooleanFieldEditor;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/GitDecoratorPreferencePage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/GitDecoratorPreferencePage.java
index 0a840c2..c9f7722 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/GitDecoratorPreferencePage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/GitDecoratorPreferencePage.java
@@ -22,10 +22,10 @@
 import java.util.Observer;
 
 import org.eclipse.core.resources.IResource;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.GitLabelProvider;
 import org.eclipse.egit.ui.internal.SWTUtils;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.decorators.GitLightweightDecorator.DecorationHelper;
 import org.eclipse.egit.ui.internal.decorators.DecorationResult;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/GitPreferenceRoot.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/GitPreferenceRoot.java
index 4167107..ce75aa4 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/GitPreferenceRoot.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/GitPreferenceRoot.java
@@ -16,8 +16,8 @@
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.variables.IStringVariableManager;
 import org.eclipse.core.variables.VariablesPlugin;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.layout.GridDataFactory;
 import org.eclipse.jface.layout.GridLayoutFactory;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/GitProjectPropertyPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/GitProjectPropertyPage.java
index 23e29ae..5a94db9 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/GitProjectPropertyPage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/GitProjectPropertyPage.java
@@ -16,8 +16,8 @@
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.commit.CommitEditor;
 import org.eclipse.egit.ui.internal.commit.RepositoryCommit;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/GlobalConfigurationPreferencePage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/GlobalConfigurationPreferencePage.java
index 5fc3665..24b66a6 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/GlobalConfigurationPreferencePage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/GlobalConfigurationPreferencePage.java
@@ -21,8 +21,8 @@
 import java.util.Map;
 import java.util.Set;
 
-import org.eclipse.egit.core.RepositoryCache;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.RepositoryCache;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.SWTUtils;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.dialogs.Dialog;
@@ -245,7 +245,7 @@
 		if (repositories == null) {
 			repositories = new ArrayList<Repository>();
 			List<String> repoPaths = Activator.getDefault().getRepositoryUtil().getConfiguredRepositories();
-			RepositoryCache repositoryCache = org.eclipse.egit.core.Activator.getDefault().getRepositoryCache();
+			RepositoryCache repositoryCache = org.eclipse.egit.core.internal.Activator.getDefault().getRepositoryCache();
 			for (String repoPath : repoPaths) {
 				File gitDir = new File(repoPath);
 				if (!gitDir.exists())
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/HistoryPreferencePage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/HistoryPreferencePage.java
index e451932..6b1e59c 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/HistoryPreferencePage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/HistoryPreferencePage.java
@@ -8,8 +8,8 @@
  *******************************************************************************/
 package org.eclipse.egit.ui.internal.preferences;
 
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.layout.GridDataFactory;
 import org.eclipse.jface.layout.GridLayoutFactory;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/ProjectsPreferencePage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/ProjectsPreferencePage.java
index 1ae3bcb..17ab280 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/ProjectsPreferencePage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/ProjectsPreferencePage.java
@@ -9,9 +9,9 @@
 package org.eclipse.egit.ui.internal.preferences;
 
 import org.eclipse.core.runtime.preferences.InstanceScope;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.GitCorePreferences;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.GitCorePreferences;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.preference.BooleanFieldEditor;
 import org.eclipse.jface.preference.FieldEditorPreferencePage;
@@ -47,7 +47,7 @@
 				UIText.ProjectsPreferencePage_RestoreBranchProjects,
 				getFieldEditorParent()) {
 			public IPreferenceStore getPreferenceStore() {
-				return org.eclipse.egit.ui.Activator.getDefault()
+				return org.eclipse.egit.ui.internal.Activator.getDefault()
 						.getPreferenceStore();
 			}
 		});
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/SynchronizePreferencePage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/SynchronizePreferencePage.java
index e5a6f35..f77d1fc 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/SynchronizePreferencePage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/SynchronizePreferencePage.java
@@ -8,8 +8,8 @@
  *******************************************************************************/
 package org.eclipse.egit.ui.internal.preferences;
 
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.preference.BooleanFieldEditor;
 import org.eclipse.jface.preference.FieldEditorPreferencePage;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/WindowCachePreferencePage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/WindowCachePreferencePage.java
index c582b29..fbbe796 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/WindowCachePreferencePage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/WindowCachePreferencePage.java
@@ -9,9 +9,9 @@
 package org.eclipse.egit.ui.internal.preferences;
 
 import org.eclipse.core.runtime.preferences.InstanceScope;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.GitCorePreferences;
-import org.eclipse.egit.core.project.GitProjectData;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.GitCorePreferences;
+import org.eclipse.egit.core.internal.project.GitProjectData;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.preference.BooleanFieldEditor;
 import org.eclipse.jface.preference.FieldEditorPreferencePage;
@@ -72,7 +72,7 @@
 			GitProjectData.reconfigureWindowCache();
 			return true;
 		} catch (RuntimeException e) {
-			org.eclipse.egit.ui.Activator.handleError(e.getMessage(), e, true);
+			org.eclipse.egit.ui.internal.Activator.handleError(e.getMessage(), e, true);
 			return false;
 		}
 	}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/provisional/wizards/GitRepositoryInfo.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/provisional/wizards/GitRepositoryInfo.java
index ab01b41..960e7a1 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/provisional/wizards/GitRepositoryInfo.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/provisional/wizards/GitRepositoryInfo.java
@@ -13,7 +13,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import org.eclipse.egit.core.securestorage.UserPasswordCredentials;
+import org.eclipse.egit.core.internal.securestorage.UserPasswordCredentials;
 
 /**
  * <p>
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/provisional/wizards/RepositoryServerInfo.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/provisional/wizards/RepositoryServerInfo.java
index 0105b88..b9b649a 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/provisional/wizards/RepositoryServerInfo.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/provisional/wizards/RepositoryServerInfo.java
@@ -12,7 +12,7 @@
 
 import java.net.URI;
 
-import org.eclipse.egit.core.securestorage.UserPasswordCredentials;
+import org.eclipse.egit.core.internal.securestorage.UserPasswordCredentials;
 
 /**
  * <p>
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/pull/MultiPullResultDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/pull/MultiPullResultDialog.java
index 76519eb..afc0727 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/pull/MultiPullResultDialog.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/pull/MultiPullResultDialog.java
@@ -20,8 +20,8 @@
 import java.util.Map.Entry;
 
 import org.eclipse.core.runtime.IStatus;
-import org.eclipse.egit.core.RepositoryUtil;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.RepositoryUtil;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.dialogs.Dialog;
 import org.eclipse.jface.dialogs.IDialogConstants;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/pull/PullOperationUI.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/pull/PullOperationUI.java
index ad8de71..d114b37 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/pull/PullOperationUI.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/pull/PullOperationUI.java
@@ -24,10 +24,10 @@
 import org.eclipse.core.runtime.jobs.IJobChangeEvent;
 import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.core.runtime.jobs.JobChangeAdapter;
-import org.eclipse.egit.core.op.PullOperation;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.JobFamilies;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.core.internal.op.PullOperation;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.JobFamilies;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.dialogs.ErrorDialog;
 import org.eclipse.jface.dialogs.MessageDialog;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/pull/PullResultDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/pull/PullResultDialog.java
index bac51ea..0444f85 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/pull/PullResultDialog.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/pull/PullResultDialog.java
@@ -11,9 +11,9 @@
  *******************************************************************************/
 package org.eclipse.egit.ui.internal.pull;
 
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIUtils;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.egit.ui.internal.UIUtils;
 import org.eclipse.egit.ui.internal.fetch.FetchResultDialog;
 import org.eclipse.egit.ui.internal.merge.MergeResultDialog;
 import org.eclipse.jface.dialogs.Dialog;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/ConfirmationPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/ConfirmationPage.java
index 3572fca..3672a03 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/ConfirmationPage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/ConfirmationPage.java
@@ -19,12 +19,12 @@
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
-import org.eclipse.egit.core.op.PushOperation;
-import org.eclipse.egit.core.op.PushOperationResult;
-import org.eclipse.egit.core.op.PushOperationSpecification;
-import org.eclipse.egit.core.securestorage.UserPasswordCredentials;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.core.internal.op.PushOperation;
+import org.eclipse.egit.core.internal.op.PushOperationResult;
+import org.eclipse.egit.core.internal.op.PushOperationSpecification;
+import org.eclipse.egit.core.internal.securestorage.UserPasswordCredentials;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.components.RepositorySelection;
 import org.eclipse.jface.dialogs.Dialog;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/PushOperationUI.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/PushOperationUI.java
index 2154d08..9ace1ed 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/PushOperationUI.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/PushOperationUI.java
@@ -23,11 +23,11 @@
 import org.eclipse.core.runtime.jobs.IJobChangeEvent;
 import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.core.runtime.jobs.JobChangeAdapter;
-import org.eclipse.egit.core.op.PushOperation;
-import org.eclipse.egit.core.op.PushOperationResult;
-import org.eclipse.egit.core.op.PushOperationSpecification;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.core.internal.op.PushOperation;
+import org.eclipse.egit.core.internal.op.PushOperationResult;
+import org.eclipse.egit.core.internal.op.PushOperationSpecification;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jgit.errors.NotSupportedException;
 import org.eclipse.jgit.lib.Repository;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/PushResultDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/PushResultDialog.java
index a948139..cafca0a 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/PushResultDialog.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/PushResultDialog.java
@@ -9,9 +9,9 @@
  *******************************************************************************/
 package org.eclipse.egit.ui.internal.push;
 
-import org.eclipse.egit.core.op.PushOperationResult;
-import org.eclipse.egit.ui.UIUtils;
+import org.eclipse.egit.core.internal.op.PushOperationResult;
 import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.egit.ui.internal.UIUtils;
 import org.eclipse.jface.dialogs.Dialog;
 import org.eclipse.jface.dialogs.IDialogConstants;
 import org.eclipse.jface.dialogs.IDialogSettings;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/PushResultTable.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/PushResultTable.java
index e1d26a0..334f945 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/PushResultTable.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/PushResultTable.java
@@ -10,10 +10,10 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import org.eclipse.egit.core.op.PushOperationResult;
-import org.eclipse.egit.ui.UIUtils;
+import org.eclipse.egit.core.internal.op.PushOperationResult;
 import org.eclipse.egit.ui.internal.UIIcons;
 import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.egit.ui.internal.UIUtils;
 import org.eclipse.egit.ui.internal.WorkbenchStyledLabelProvider;
 import org.eclipse.egit.ui.internal.commit.CommitEditor;
 import org.eclipse.egit.ui.internal.commit.RepositoryCommit;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/PushToGerritPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/PushToGerritPage.java
index 296a069..860fd33 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/PushToGerritPage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/PushToGerritPage.java
@@ -23,12 +23,12 @@
 
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.egit.core.op.PushOperationResult;
-import org.eclipse.egit.core.op.PushOperationSpecification;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
-import org.eclipse.egit.ui.UIUtils;
+import org.eclipse.egit.core.internal.op.PushOperationResult;
+import org.eclipse.egit.core.internal.op.PushOperationSpecification;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.egit.ui.internal.UIUtils;
 import org.eclipse.egit.ui.internal.credentials.EGitCredentialsProvider;
 import org.eclipse.jface.bindings.keys.KeyStroke;
 import org.eclipse.jface.bindings.keys.ParseException;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/PushWizard.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/PushWizard.java
index ad7d3b7..7f46596 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/PushWizard.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/PushWizard.java
@@ -21,14 +21,14 @@
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.egit.core.op.PushOperation;
-import org.eclipse.egit.core.op.PushOperationResult;
-import org.eclipse.egit.core.op.PushOperationSpecification;
-import org.eclipse.egit.core.securestorage.UserPasswordCredentials;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.core.internal.op.PushOperation;
+import org.eclipse.egit.core.internal.op.PushOperationResult;
+import org.eclipse.egit.core.internal.op.PushOperationSpecification;
+import org.eclipse.egit.core.internal.securestorage.UserPasswordCredentials;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.SecureStoreUtils;
 import org.eclipse.egit.ui.internal.UIIcons;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.components.RefSpecPage;
 import org.eclipse.egit.ui.internal.components.RepositorySelection;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/RefSpecDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/RefSpecDialog.java
index 67037f4..0a3899a 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/RefSpecDialog.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/RefSpecDialog.java
@@ -10,9 +10,9 @@
 
 import java.util.List;
 
-import org.eclipse.egit.ui.UIUtils;
-import org.eclipse.egit.ui.UIUtils.IRefListProvider;
 import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.egit.ui.internal.UIUtils;
+import org.eclipse.egit.ui.internal.UIUtils.IRefListProvider;
 import org.eclipse.egit.ui.internal.components.RefContentAssistProvider;
 import org.eclipse.jface.dialogs.TitleAreaDialog;
 import org.eclipse.jface.layout.GridDataFactory;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/RefUpdateContentProvider.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/RefUpdateContentProvider.java
index d9b6d38..5759c78 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/RefUpdateContentProvider.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/RefUpdateContentProvider.java
@@ -8,7 +8,7 @@
  *******************************************************************************/
 package org.eclipse.egit.ui.internal.push;
 
-import org.eclipse.egit.core.op.PushOperationResult;
+import org.eclipse.egit.core.internal.op.PushOperationResult;
 import org.eclipse.egit.ui.internal.commit.RepositoryCommit;
 import org.eclipse.ui.model.WorkbenchContentProvider;
 
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/RefUpdateElement.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/RefUpdateElement.java
index 0e511f5..f704368 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/RefUpdateElement.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/RefUpdateElement.java
@@ -13,8 +13,8 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import org.eclipse.egit.core.op.PushOperationResult;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.op.PushOperationResult;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.DecorationOverlayDescriptor;
 import org.eclipse.egit.ui.internal.UIIcons;
 import org.eclipse.egit.ui.internal.UIText;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/SimpleConfigurePushDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/SimpleConfigurePushDialog.java
index a6ddeb6..45bc682 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/SimpleConfigurePushDialog.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/SimpleConfigurePushDialog.java
@@ -17,9 +17,9 @@
 
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.egit.core.op.PushOperationResult;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.core.internal.op.PushOperationResult;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.repository.SelectUriWizard;
 import org.eclipse.jface.dialogs.Dialog;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/SimplePushRefWizard.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/SimplePushRefWizard.java
index 616a6ff..19babdd 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/SimplePushRefWizard.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/push/SimplePushRefWizard.java
@@ -14,10 +14,10 @@
 import java.util.Collections;
 import java.util.List;
 
-import org.eclipse.egit.core.op.PushOperation;
-import org.eclipse.egit.core.op.PushOperationSpecification;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.core.internal.op.PushOperation;
+import org.eclipse.egit.core.internal.op.PushOperationSpecification;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.components.RefContentAssistProvider;
 import org.eclipse.egit.ui.internal.components.RepositorySelection;
 import org.eclipse.egit.ui.internal.components.RepositorySelectionPage;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/rebase/RebaseHelper.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/rebase/RebaseHelper.java
index c35b069..dd8b0f1 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/rebase/RebaseHelper.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/rebase/RebaseHelper.java
@@ -19,8 +19,8 @@
 import org.eclipse.core.runtime.jobs.IJobChangeEvent;
 import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.core.runtime.jobs.JobChangeAdapter;
-import org.eclipse.egit.core.op.RebaseOperation;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.op.RebaseOperation;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.jgit.api.RebaseCommand.Operation;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/rebase/RebaseResultDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/rebase/RebaseResultDialog.java
index eaf6bc9..2547037 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/rebase/RebaseResultDialog.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/rebase/RebaseResultDialog.java
@@ -31,10 +31,10 @@
 import org.eclipse.egit.core.internal.FileChecker;
 import org.eclipse.egit.core.internal.FileChecker.CheckResult;
 import org.eclipse.egit.core.internal.FileChecker.CheckResultEntry;
-import org.eclipse.egit.core.op.RebaseOperation;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.core.internal.op.RebaseOperation;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.dialogs.CheckoutConflictDialog;
 import org.eclipse.egit.ui.internal.merge.GitMergeEditorInput;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/reflog/ReflogView.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/reflog/ReflogView.java
index 097b2f7..1ee554d 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/reflog/ReflogView.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/reflog/ReflogView.java
@@ -18,11 +18,11 @@
 
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIUtils;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIIcons;
 import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.egit.ui.internal.UIUtils;
 import org.eclipse.egit.ui.internal.commit.CommitEditor;
 import org.eclipse.egit.ui.internal.commit.RepositoryCommit;
 import org.eclipse.egit.ui.internal.reflog.ReflogViewContentProvider.ReflogInput;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/reflog/ReflogViewContentProvider.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/reflog/ReflogViewContentProvider.java
index 90c7fae..b865c3d 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/reflog/ReflogViewContentProvider.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/reflog/ReflogViewContentProvider.java
@@ -12,7 +12,7 @@
 package org.eclipse.egit.ui.internal.reflog;
 
 import org.eclipse.core.runtime.Assert;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.jface.viewers.ITreeContentProvider;
 import org.eclipse.jface.viewers.Viewer;
 import org.eclipse.jgit.api.Git;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/CreateBranchPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/CreateBranchPage.java
index 05b0366..19fb503 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/CreateBranchPage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/CreateBranchPage.java
@@ -22,9 +22,9 @@
 
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.egit.core.op.CreateLocalBranchOperation;
-import org.eclipse.egit.core.op.CreateLocalBranchOperation.UpstreamConfig;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.op.CreateLocalBranchOperation;
+import org.eclipse.egit.core.internal.op.CreateLocalBranchOperation.UpstreamConfig;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.CommonUtils;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.ValidationUtils;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/CreateBranchWizard.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/CreateBranchWizard.java
index 147aa5a..47ba5b0 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/CreateBranchWizard.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/CreateBranchWizard.java
@@ -15,7 +15,7 @@
 
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.operation.IRunnableWithProgress;
 import org.eclipse.jface.wizard.Wizard;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/CreateRepositoryPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/CreateRepositoryPage.java
index eed505c..aa8087d 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/CreateRepositoryPage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/CreateRepositoryPage.java
@@ -17,8 +17,8 @@
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.layout.GridDataFactory;
 import org.eclipse.jface.wizard.WizardPage;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/DropAdapterAssistant.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/DropAdapterAssistant.java
index a985dda..ad7d2d8 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/DropAdapterAssistant.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/DropAdapterAssistant.java
@@ -14,7 +14,7 @@
 
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.RepositoryCache.FileKey;
 import org.eclipse.jgit.util.FS;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/NewRepositoryWizard.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/NewRepositoryWizard.java
index f7d521f..37f3212 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/NewRepositoryWizard.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/NewRepositoryWizard.java
@@ -13,8 +13,8 @@
 import java.io.File;
 import java.io.IOException;
 
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.RepositoryCache;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.RepositoryCache;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.jface.wizard.Wizard;
@@ -67,7 +67,7 @@
 					.addConfiguredRepository(repoFile);
 			this.newRepo = repoToCreate;
 		} catch (IOException e) {
-			org.eclipse.egit.ui.Activator.handleError(e.getMessage(), e, false);
+			org.eclipse.egit.ui.internal.Activator.handleError(e.getMessage(), e, false);
 		}
 		return true;
 	}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoriesView.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoriesView.java
index 66babdd..cc96796 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoriesView.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoriesView.java
@@ -38,15 +38,15 @@
 import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener;
 import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;
-import org.eclipse.egit.core.AdapterUtils;
-import org.eclipse.egit.core.RepositoryCache;
-import org.eclipse.egit.core.RepositoryUtil;
+import org.eclipse.egit.core.internal.AdapterUtils;
+import org.eclipse.egit.core.internal.RepositoryCache;
+import org.eclipse.egit.core.internal.RepositoryUtil;
 import org.eclipse.egit.core.internal.util.ResourceUtil;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.JobFamilies;
-import org.eclipse.egit.ui.UIUtils;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIIcons;
 import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.egit.ui.internal.UIUtils;
 import org.eclipse.egit.ui.internal.history.HistoryPageInput;
 import org.eclipse.egit.ui.internal.reflog.ReflogView;
 import org.eclipse.egit.ui.internal.repository.tree.FetchNode;
@@ -188,7 +188,7 @@
 	 */
 	public RepositoriesView() {
 		repositoryUtil = Activator.getDefault().getRepositoryUtil();
-		repositoryCache = org.eclipse.egit.core.Activator.getDefault()
+		repositoryCache = org.eclipse.egit.core.internal.Activator.getDefault()
 				.getRepositoryCache();
 
 		configurationListener = new IPreferenceChangeListener() {
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoriesViewActionProvider.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoriesViewActionProvider.java
index 1f85ec7..23dc15d 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoriesViewActionProvider.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoriesViewActionProvider.java
@@ -8,7 +8,7 @@
  *******************************************************************************/
 package org.eclipse.egit.ui.internal.repository;
 
-import org.eclipse.egit.ui.UIUtils;
+import org.eclipse.egit.ui.internal.UIUtils;
 import org.eclipse.egit.ui.internal.repository.tree.FetchNode;
 import org.eclipse.egit.ui.internal.repository.tree.FileNode;
 import org.eclipse.egit.ui.internal.repository.tree.FolderNode;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoriesViewContentProvider.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoriesViewContentProvider.java
index fc4ada3..83e2324 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoriesViewContentProvider.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoriesViewContentProvider.java
@@ -31,9 +31,9 @@
 import org.eclipse.core.resources.IWorkspaceRoot;
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.core.RepositoryCache;
-import org.eclipse.egit.core.RepositoryUtil;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.RepositoryCache;
+import org.eclipse.egit.core.internal.RepositoryUtil;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.repository.tree.AdditionalRefNode;
 import org.eclipse.egit.ui.internal.repository.tree.AdditionalRefsNode;
@@ -81,7 +81,7 @@
  */
 public class RepositoriesViewContentProvider implements ITreeContentProvider,
 		IStateListener {
-	private final RepositoryCache repositoryCache = org.eclipse.egit.core.Activator
+	private final RepositoryCache repositoryCache = org.eclipse.egit.core.internal.Activator
 			.getDefault().getRepositoryCache();
 
 	private final State commandState;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoriesViewLabelProvider.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoriesViewLabelProvider.java
index 5290dc8..e9c4c68 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoriesViewLabelProvider.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoriesViewLabelProvider.java
@@ -20,7 +20,7 @@
 import org.eclipse.core.commands.IStateListener;
 import org.eclipse.core.commands.State;
 import org.eclipse.core.runtime.IPath;
-import org.eclipse.egit.core.Activator;
+import org.eclipse.egit.core.internal.Activator;
 import org.eclipse.egit.ui.internal.GitLabelProvider;
 import org.eclipse.egit.ui.internal.UIIcons;
 import org.eclipse.egit.ui.internal.UIText;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoryPropertyPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoryPropertyPage.java
index f651159..ee47a15 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoryPropertyPage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoryPropertyPage.java
@@ -13,7 +13,7 @@
 import java.io.File;
 import java.io.IOException;
 
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.preferences.ConfigurationEditorComponent;
 import org.eclipse.jface.layout.GridDataFactory;
 import org.eclipse.jface.layout.GridLayoutFactory;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoryPropertySource.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoryPropertySource.java
index 9424340..d71b2f0 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoryPropertySource.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoryPropertySource.java
@@ -16,7 +16,7 @@
 import java.util.List;
 import java.util.StringTokenizer;
 
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIIcons;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.preferences.ConfigurationEditorComponent;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoryRemotePropertySource.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoryRemotePropertySource.java
index 3cf6cb5..80c8ddd 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoryRemotePropertySource.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositoryRemotePropertySource.java
@@ -14,7 +14,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.eclipse.jgit.lib.StoredConfig;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositorySearchDialog.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositorySearchDialog.java
index 9fa0524..0c98809 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositorySearchDialog.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/RepositorySearchDialog.java
@@ -23,13 +23,13 @@
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.preferences.IEclipsePreferences;
 import org.eclipse.core.runtime.preferences.InstanceScope;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.ui.UIPreferences;
-import org.eclipse.egit.ui.UIUtils;
+import org.eclipse.egit.core.internal.Activator;
 import org.eclipse.egit.ui.internal.CachedCheckboxTreeViewer;
 import org.eclipse.egit.ui.internal.FilteredCheckboxTree;
 import org.eclipse.egit.ui.internal.UIIcons;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.egit.ui.internal.UIUtils;
 import org.eclipse.jface.dialogs.IMessageProvider;
 import org.eclipse.jface.layout.GridDataFactory;
 import org.eclipse.jface.operation.IRunnableWithProgress;
@@ -220,7 +220,7 @@
 				false).hint(300, SWT.DEFAULT).applyTo(dir);
 		dir.setToolTipText(UIText.RepositorySearchDialog_EnterDirectoryToolTip);
 
-		String defaultRepoPath = org.eclipse.egit.ui.Activator.getDefault()
+		String defaultRepoPath = org.eclipse.egit.ui.internal.Activator.getDefault()
 				.getPreferenceStore().getString(UIPreferences.DEFAULT_REPO_DIR);
 
 		String initialPath = prefs.get(PREF_PATH, defaultRepoPath);
@@ -483,7 +483,7 @@
 		try {
 			getContainer().run(true, true, action);
 		} catch (InvocationTargetException e1) {
-			org.eclipse.egit.ui.Activator.handleError(
+			org.eclipse.egit.ui.internal.Activator.handleError(
 					UIText.RepositorySearchDialog_errorOccurred, e1, true);
 		} catch (InterruptedException e1) {
 			// ignore
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/SelectResetTypePage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/SelectResetTypePage.java
index 1ff7cd0..67e0359 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/SelectResetTypePage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/SelectResetTypePage.java
@@ -13,9 +13,9 @@
 
 import java.io.IOException;
 
-import org.eclipse.egit.ui.UIUtils;
 import org.eclipse.egit.ui.internal.UIIcons;
 import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.egit.ui.internal.UIUtils;
 import org.eclipse.jface.dialogs.Dialog;
 import org.eclipse.jface.layout.GridDataFactory;
 import org.eclipse.jface.layout.GridLayoutFactory;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/SelectUriWizard.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/SelectUriWizard.java
index b9b1ea0..fc0f825 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/SelectUriWizard.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/SelectUriWizard.java
@@ -10,7 +10,7 @@
  *******************************************************************************/
 package org.eclipse.egit.ui.internal.repository;
 
-import org.eclipse.egit.core.securestorage.UserPasswordCredentials;
+import org.eclipse.egit.core.internal.securestorage.UserPasswordCredentials;
 import org.eclipse.egit.ui.internal.SecureStoreUtils;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.components.RepositorySelectionPage;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/LinkHelper.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/LinkHelper.java
index bfb61af..961a809 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/LinkHelper.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/LinkHelper.java
@@ -18,8 +18,8 @@
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.core.RepositoryUtil;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.RepositoryUtil;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.repository.RepositoriesViewContentProvider;
 import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.jface.viewers.StructuredSelection;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/AddToIndexCommand.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/AddToIndexCommand.java
index 17ca44c1..fa5af8a 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/AddToIndexCommand.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/AddToIndexCommand.java
@@ -15,7 +15,7 @@
 import org.eclipse.core.commands.ExecutionException;
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.repository.tree.FileNode;
 import org.eclipse.jgit.api.AddCommand;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/ChangeCredentialsCommand.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/ChangeCredentialsCommand.java
index 43d40f5..e2f1dbe 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/ChangeCredentialsCommand.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/ChangeCredentialsCommand.java
@@ -12,7 +12,7 @@
 
 import org.eclipse.core.commands.ExecutionEvent;
 import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.credentials.LoginService;
 import org.eclipse.egit.ui.internal.repository.tree.RepositoryTreeNode;
 import org.eclipse.jgit.transport.URIish;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/ClearCredentialsCommand.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/ClearCredentialsCommand.java
index f9d84fb..f65c0f9 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/ClearCredentialsCommand.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/ClearCredentialsCommand.java
@@ -13,7 +13,7 @@
 
 import org.eclipse.core.commands.ExecutionEvent;
 import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.repository.tree.RepositoryTreeNode;
 import org.eclipse.jgit.transport.URIish;
@@ -37,7 +37,7 @@
 			return null;
 		}
 		try {
-			org.eclipse.egit.core.Activator.getDefault().getSecureStore().clearCredentials(uri);
+			org.eclipse.egit.core.internal.Activator.getDefault().getSecureStore().clearCredentials(uri);
 		} catch (IOException e) {
 			Activator.handleError(UIText.ClearCredentialsCommand_clearingCredentialsFailed, e, true);
 		}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/CreateBranchCommand.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/CreateBranchCommand.java
index c6b49d8..7b1c063 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/CreateBranchCommand.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/CreateBranchCommand.java
@@ -16,7 +16,7 @@
 
 import org.eclipse.core.commands.ExecutionEvent;
 import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.repository.CreateBranchWizard;
 import org.eclipse.egit.ui.internal.repository.tree.RepositoryTreeNode;
 import org.eclipse.egit.ui.internal.repository.tree.RepositoryTreeNodeType;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/CreateTagCommand.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/CreateTagCommand.java
index 64b13a1..35d9155 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/CreateTagCommand.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/CreateTagCommand.java
@@ -20,9 +20,9 @@
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.egit.core.op.TagOperation;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.core.internal.op.TagOperation;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.decorators.GitLightweightDecorator;
 import org.eclipse.egit.ui.internal.dialogs.CreateTagDialog;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/DeleteBranchCommand.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/DeleteBranchCommand.java
index 9db5a1c..e1a5cd2 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/DeleteBranchCommand.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/DeleteBranchCommand.java
@@ -21,8 +21,8 @@
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.egit.core.op.DeleteBranchOperation;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.op.DeleteBranchOperation;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.dialogs.UnmergedBranchDialog;
 import org.eclipse.egit.ui.internal.repository.tree.RefNode;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/DeleteFetchCommand.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/DeleteFetchCommand.java
index 0c22ba7..60681a4 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/DeleteFetchCommand.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/DeleteFetchCommand.java
@@ -14,7 +14,7 @@
 
 import org.eclipse.core.commands.ExecutionEvent;
 import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.repository.tree.FetchNode;
 import org.eclipse.egit.ui.internal.repository.tree.RemoteNode;
 import org.eclipse.jgit.lib.StoredConfig;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/DeletePushCommand.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/DeletePushCommand.java
index 3c1336e..e27f043 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/DeletePushCommand.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/DeletePushCommand.java
@@ -14,7 +14,7 @@
 
 import org.eclipse.core.commands.ExecutionEvent;
 import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.repository.tree.PushNode;
 import org.eclipse.egit.ui.internal.repository.tree.RemoteNode;
 import org.eclipse.jgit.lib.StoredConfig;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/DeleteTagCommand.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/DeleteTagCommand.java
index 46e88c8..111f75b 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/DeleteTagCommand.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/DeleteTagCommand.java
@@ -21,9 +21,9 @@
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.egit.core.op.DeleteTagOperation;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.core.internal.op.DeleteTagOperation;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.repository.tree.TagNode;
 import org.eclipse.jface.dialogs.MessageDialog;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/FetchCommand.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/FetchCommand.java
index 9c13b01..8901f24 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/FetchCommand.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/FetchCommand.java
@@ -14,7 +14,7 @@
 
 import org.eclipse.core.commands.ExecutionEvent;
 import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.fetch.FetchWizard;
 import org.eclipse.egit.ui.internal.repository.tree.RepositoryNode;
 import org.eclipse.jface.wizard.WizardDialog;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/FetchConfiguredRemoteCommand.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/FetchConfiguredRemoteCommand.java
index bbbc804..f87c6dc 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/FetchConfiguredRemoteCommand.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/FetchConfiguredRemoteCommand.java
@@ -18,8 +18,8 @@
 import org.eclipse.core.commands.ExecutionEvent;
 import org.eclipse.core.commands.ExecutionException;
 import org.eclipse.core.expressions.IEvaluationContext;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.fetch.FetchOperationUI;
 import org.eclipse.egit.ui.internal.fetch.SimpleConfigureFetchDialog;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/GarbageCollectCommand.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/GarbageCollectCommand.java
index 0320f1d..19dfe44 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/GarbageCollectCommand.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/GarbageCollectCommand.java
@@ -19,8 +19,8 @@
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.egit.core.op.GarbageCollectOperation;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.op.GarbageCollectOperation;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.repository.tree.RepositoryNode;
 import org.eclipse.jgit.lib.Repository;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/MergeCommand.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/MergeCommand.java
index 6ad6f4b..e133871 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/MergeCommand.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/MergeCommand.java
@@ -24,8 +24,8 @@
 import org.eclipse.core.runtime.jobs.IJobChangeEvent;
 import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.core.runtime.jobs.JobChangeAdapter;
-import org.eclipse.egit.core.op.MergeOperation;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.op.MergeOperation;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.dialogs.BasicConfigurationDialog;
 import org.eclipse.egit.ui.internal.dialogs.MergeTargetSelectionDialog;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/OpenInEditorCommand.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/OpenInEditorCommand.java
index 19c5640..e481ae7 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/OpenInEditorCommand.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/OpenInEditorCommand.java
@@ -18,7 +18,7 @@
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.repository.tree.FileNode;
 import org.eclipse.ui.PartInitException;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/PasteCommand.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/PasteCommand.java
index 4c6b6f9..34006ae 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/PasteCommand.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/PasteCommand.java
@@ -16,7 +16,7 @@
 
 import org.eclipse.core.commands.ExecutionEvent;
 import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.components.RepositorySelectionPage.Protocol;
 import org.eclipse.egit.ui.internal.repository.tree.RepositoryTreeNode;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/PushCommand.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/PushCommand.java
index 2cea5f0..e336878 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/PushCommand.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/PushCommand.java
@@ -14,7 +14,7 @@
 
 import org.eclipse.core.commands.ExecutionEvent;
 import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.push.PushWizard;
 import org.eclipse.egit.ui.internal.push.SimplePushRefWizard;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/PushConfiguredRemoteCommand.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/PushConfiguredRemoteCommand.java
index 46d935c..4f7128b 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/PushConfiguredRemoteCommand.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/PushConfiguredRemoteCommand.java
@@ -19,8 +19,8 @@
 import org.eclipse.core.commands.ExecutionEvent;
 import org.eclipse.core.commands.ExecutionException;
 import org.eclipse.core.expressions.IEvaluationContext;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.push.PushOperationUI;
 import org.eclipse.egit.ui.internal.push.SimpleConfigurePushDialog;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/RemoveCommand.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/RemoveCommand.java
index e7b9307..935769a 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/RemoveCommand.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/RemoveCommand.java
@@ -31,8 +31,8 @@
 import org.eclipse.core.runtime.Path;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.repository.tree.RepositoryNode;
 import org.eclipse.egit.ui.internal.repository.tree.RepositoryTreeNodeType;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/RemoveRemoteCommand.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/RemoveRemoteCommand.java
index 8f6a719..69e8622 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/RemoveRemoteCommand.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/RemoveRemoteCommand.java
@@ -14,7 +14,7 @@
 
 import org.eclipse.core.commands.ExecutionEvent;
 import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.repository.RepositoriesView;
 import org.eclipse.egit.ui.internal.repository.tree.RemoteNode;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/RepositoriesViewCommandHandler.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/RepositoriesViewCommandHandler.java
index 94aa9b2..3054df1 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/RepositoriesViewCommandHandler.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/RepositoriesViewCommandHandler.java
@@ -25,8 +25,8 @@
 import org.eclipse.core.commands.ExecutionException;
 import org.eclipse.core.expressions.IEvaluationContext;
 import org.eclipse.core.runtime.IPath;
-import org.eclipse.egit.core.RepositoryUtil;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.RepositoryUtil;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.repository.RepositoriesView;
 import org.eclipse.egit.ui.internal.repository.tree.FileNode;
 import org.eclipse.egit.ui.internal.repository.tree.FolderNode;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/ResetCommand.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/ResetCommand.java
index d98da75..65c4605 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/ResetCommand.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/ResetCommand.java
@@ -17,9 +17,9 @@
 import org.eclipse.core.commands.ExecutionException;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.egit.core.internal.job.JobUtil;
-import org.eclipse.egit.core.op.ResetOperation;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.core.internal.op.ResetOperation;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.repository.SelectResetTypePage;
 import org.eclipse.egit.ui.internal.repository.tree.RepositoryTreeNode;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/StashApplyCommand.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/StashApplyCommand.java
index b326017..67e8877 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/StashApplyCommand.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/StashApplyCommand.java
@@ -20,9 +20,9 @@
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.egit.core.op.StashApplyOperation;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.core.internal.op.StashApplyOperation;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.repository.tree.StashedCommitNode;
 import org.eclipse.jgit.lib.Repository;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/StashDropCommand.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/StashDropCommand.java
index 3c1ea4e..87bff79 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/StashDropCommand.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/StashDropCommand.java
@@ -21,9 +21,9 @@
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.egit.core.op.StashDropOperation;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.core.internal.op.StashDropOperation;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.repository.tree.StashedCommitNode;
 import org.eclipse.jface.dialogs.MessageDialog;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/SubmoduleAddCommand.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/SubmoduleAddCommand.java
index 4e9a98b..69fb04b 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/SubmoduleAddCommand.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/SubmoduleAddCommand.java
@@ -20,9 +20,9 @@
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.egit.core.op.SubmoduleAddOperation;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.core.internal.op.SubmoduleAddOperation;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.repository.tree.RepositoryTreeNode;
 import org.eclipse.egit.ui.internal.submodule.AddSubmoduleWizard;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/SubmoduleSyncCommand.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/SubmoduleSyncCommand.java
index be9a535..f31d23f 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/SubmoduleSyncCommand.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/SubmoduleSyncCommand.java
@@ -22,9 +22,9 @@
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.SubProgressMonitor;
 import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.egit.core.op.SubmoduleSyncOperation;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.core.internal.op.SubmoduleSyncOperation;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.repository.tree.RepositoryTreeNode;
 import org.eclipse.jgit.lib.Repository;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/SubmoduleUpdateCommand.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/SubmoduleUpdateCommand.java
index 4712c04..3d3b14c 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/SubmoduleUpdateCommand.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/SubmoduleUpdateCommand.java
@@ -23,9 +23,9 @@
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.SubProgressMonitor;
 import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.egit.core.op.SubmoduleUpdateOperation;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.core.internal.op.SubmoduleUpdateOperation;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.repository.tree.RepositoryTreeNode;
 import org.eclipse.jgit.lib.Repository;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/SynchronizeCommand.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/SynchronizeCommand.java
index 4d7f503..a61e2b3 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/SynchronizeCommand.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/repository/tree/command/SynchronizeCommand.java
@@ -22,8 +22,8 @@
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeData;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.repository.tree.RepositoryTreeNode;
 import org.eclipse.egit.ui.internal.synchronize.GitModelSynchronize;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/search/CommitSearchPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/search/CommitSearchPage.java
index 486dcce..6296573 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/search/CommitSearchPage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/search/CommitSearchPage.java
@@ -21,10 +21,10 @@
 import java.util.regex.PatternSyntaxException;
 
 import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIUtils;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIIcons;
 import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.egit.ui.internal.UIUtils;
 import org.eclipse.egit.ui.internal.repository.RepositoriesViewContentProvider;
 import org.eclipse.egit.ui.internal.repository.RepositoriesViewLabelProvider;
 import org.eclipse.egit.ui.internal.repository.tree.RepositoryNode;
@@ -469,7 +469,7 @@
 			if (file.exists())
 				try {
 					RepositoryNode node = new RepositoryNode(null,
-							org.eclipse.egit.core.Activator.getDefault()
+							org.eclipse.egit.core.internal.Activator.getDefault()
 									.getRepositoryCache()
 									.lookupRepository(file));
 					repositories.add(node);
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/search/CommitSearchQuery.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/search/CommitSearchQuery.java
index 3496e3f..e57565c 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/search/CommitSearchQuery.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/search/CommitSearchQuery.java
@@ -21,7 +21,7 @@
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.OperationCanceledException;
 import org.eclipse.core.runtime.Status;
-import org.eclipse.egit.core.Activator;
+import org.eclipse.egit.core.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.commit.RepositoryCommit;
 import org.eclipse.jgit.lib.Constants;
@@ -183,7 +183,7 @@
 				walkRepository(repo, pattern, monitor);
 			}
 		} catch (IOException e) {
-			org.eclipse.egit.ui.Activator.handleError(
+			org.eclipse.egit.ui.internal.Activator.handleError(
 					"Error searching commits", e, true); //$NON-NLS-1$
 		}
 		return Status.OK_STATUS;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/sharing/ExistingOrNewPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/sharing/ExistingOrNewPage.java
index df09fc0..aea9b8c 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/sharing/ExistingOrNewPage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/sharing/ExistingOrNewPage.java
@@ -24,10 +24,10 @@
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.core.RepositoryUtil;
-import org.eclipse.egit.core.project.RepositoryFinder;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.RepositoryUtil;
+import org.eclipse.egit.core.internal.project.RepositoryFinder;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIIcons;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.repository.NewRepositoryWizard;
@@ -398,12 +398,12 @@
 					String msg = NLS
 							.bind(UIText.ExistingOrNewPage_ErrorFailedToCreateRepository,
 									gitDir.toString());
-					org.eclipse.egit.ui.Activator.handleError(msg, e1, true);
+					org.eclipse.egit.ui.internal.Activator.handleError(msg, e1, true);
 				} catch (CoreException e2) {
 					String msg = NLS
 							.bind(UIText.ExistingOrNewPage_ErrorFailedToRefreshRepository,
 									gitDir);
-					org.eclipse.egit.ui.Activator.handleError(msg, e2, true);
+					org.eclipse.egit.ui.internal.Activator.handleError(msg, e2, true);
 				}
 				for (TreeItem ti : tree.getSelection()) {
 					ti.setText(2, gitDir.toString());
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/sharing/RepoComboContentProvider.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/sharing/RepoComboContentProvider.java
index 4506596..e462067 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/sharing/RepoComboContentProvider.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/sharing/RepoComboContentProvider.java
@@ -13,9 +13,9 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import org.eclipse.egit.core.RepositoryCache;
-import org.eclipse.egit.core.RepositoryUtil;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.RepositoryCache;
+import org.eclipse.egit.core.internal.RepositoryUtil;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.jface.viewers.IStructuredContentProvider;
 import org.eclipse.jface.viewers.Viewer;
 import org.eclipse.jgit.lib.Repository;
@@ -28,7 +28,7 @@
 	private final RepositoryUtil util = Activator.getDefault()
 			.getRepositoryUtil();
 
-	private final RepositoryCache cache = org.eclipse.egit.core.Activator
+	private final RepositoryCache cache = org.eclipse.egit.core.internal.Activator
 			.getDefault().getRepositoryCache();
 
 	public void dispose() {
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/sharing/RepoComboLabelProvider.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/sharing/RepoComboLabelProvider.java
index 9a13de6..4d0fead 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/sharing/RepoComboLabelProvider.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/sharing/RepoComboLabelProvider.java
@@ -8,8 +8,8 @@
  *******************************************************************************/
 package org.eclipse.egit.ui.internal.sharing;
 
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.RepositoryUtil;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.RepositoryUtil;
 import org.eclipse.egit.ui.internal.repository.RepositoriesView;
 import org.eclipse.jface.viewers.BaseLabelProvider;
 import org.eclipse.jface.viewers.ComboViewer;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/sharing/SharingWizard.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/sharing/SharingWizard.java
index b93d3d3..b59a8a8 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/sharing/SharingWizard.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/sharing/SharingWizard.java
@@ -24,8 +24,8 @@
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.core.op.ConnectProviderOperation;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.op.ConnectProviderOperation;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.operation.IRunnableWithProgress;
 import org.eclipse.jface.wizard.Wizard;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingView.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingView.java
index 0e528ad..df4c094 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingView.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingView.java
@@ -37,19 +37,19 @@
 import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener;
 import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;
 import org.eclipse.core.runtime.preferences.InstanceScope;
-import org.eclipse.egit.core.AdapterUtils;
-import org.eclipse.egit.core.RepositoryUtil;
+import org.eclipse.egit.core.internal.AdapterUtils;
+import org.eclipse.egit.core.internal.RepositoryUtil;
 import org.eclipse.egit.core.internal.indexdiff.IndexDiffCacheEntry;
 import org.eclipse.egit.core.internal.indexdiff.IndexDiffChangedListener;
 import org.eclipse.egit.core.internal.indexdiff.IndexDiffData;
-import org.eclipse.egit.core.op.CommitOperation;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
-import org.eclipse.egit.ui.UIUtils;
+import org.eclipse.egit.core.internal.op.CommitOperation;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.EgitUiEditorUtils;
 import org.eclipse.egit.ui.internal.UIIcons;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.egit.ui.internal.UIUtils;
 import org.eclipse.egit.ui.internal.actions.ActionCommands;
 import org.eclipse.egit.ui.internal.actions.BooleanPrefAction;
 import org.eclipse.egit.ui.internal.commit.CommitHelper;
@@ -580,7 +580,7 @@
 			preferenceStore.setDefault(UIPreferences.STAGING_VIEW_SYNC_SELECTION, true);
 
 		InstanceScope.INSTANCE.getNode(
-				org.eclipse.egit.core.Activator.getPluginId())
+				org.eclipse.egit.core.internal.Activator.getPluginId())
 				.addPreferenceChangeListener(prefListener);
 
 		updateSectionText();
@@ -1382,7 +1382,7 @@
 		return repository != null
 				&& !repository.isBare()
 				&& repository.getWorkTree().exists()
-				&& org.eclipse.egit.core.Activator.getDefault()
+				&& org.eclipse.egit.core.internal.Activator.getDefault()
 						.getRepositoryUtil().contains(repository);
 	}
 
@@ -1446,7 +1446,7 @@
 	private IndexDiffData doReload(final Repository repository) {
 		currentRepository = repository;
 
-		IndexDiffCacheEntry entry = org.eclipse.egit.core.Activator.getDefault().getIndexDiffCache().getIndexDiffCacheEntry(currentRepository);
+		IndexDiffCacheEntry entry = org.eclipse.egit.core.internal.Activator.getDefault().getIndexDiffCache().getIndexDiffCacheEntry(currentRepository);
 
 		if(cacheEntry != null && cacheEntry != entry)
 			cacheEntry.removeIndexDiffChangedListener(myIndexDiffListener);
@@ -1566,7 +1566,7 @@
 			message = message.replace(chIdLine, ""); //$NON-NLS-1$
 		}
 
-		if (org.eclipse.egit.ui.Activator.getDefault().getPreferenceStore()
+		if (org.eclipse.egit.ui.internal.Activator.getDefault().getPreferenceStore()
 				.getBoolean(UIPreferences.COMMIT_DIALOG_SIGNED_OFF_BY)
 				&& commitMessageComponent.isSignedOff()
 				&& message.trim().equals(
@@ -1685,7 +1685,7 @@
 			undoRedoActionGroup.dispose();
 
 		InstanceScope.INSTANCE.getNode(
-				org.eclipse.egit.core.Activator.getPluginId())
+				org.eclipse.egit.core.internal.Activator.getPluginId())
 				.removePreferenceChangeListener(prefListener);
 	}
 
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingViewContentProvider.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingViewContentProvider.java
index 7fa7fca..feeade8 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingViewContentProvider.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingViewContentProvider.java
@@ -24,7 +24,7 @@
 import java.util.TreeSet;
 
 import org.eclipse.egit.core.internal.indexdiff.IndexDiffData;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.staging.StagingView.StagingViewUpdate;
 import org.eclipse.jface.viewers.IStructuredContentProvider;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingViewLabelProvider.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingViewLabelProvider.java
index 92f944b..d8f0104 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingViewLabelProvider.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingViewLabelProvider.java
@@ -10,7 +10,7 @@
 
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIIcons;
 import org.eclipse.egit.ui.internal.decorators.DecorationResult;
 import org.eclipse.egit.ui.internal.decorators.GitLightweightDecorator.DecorationHelper;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/stash/StashCreateUI.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/stash/StashCreateUI.java
index 73c6c81..b8965c5 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/stash/StashCreateUI.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/stash/StashCreateUI.java
@@ -16,9 +16,9 @@
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.egit.core.op.StashCreateOperation;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.core.internal.op.StashCreateOperation;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.dialogs.InputDialog;
 import org.eclipse.jface.dialogs.MessageDialog;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitChangeSetModelProvider.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitChangeSetModelProvider.java
index 6ce5725..f751c67 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitChangeSetModelProvider.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitChangeSetModelProvider.java
@@ -16,10 +16,10 @@
 import org.eclipse.core.resources.mapping.ResourceMappingContext;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.synchronize.GitSubscriberResourceMappingContext;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.synchronize.GitSubscriberResourceMappingContext;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeData;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeDataSet;
 import org.eclipse.egit.ui.internal.synchronize.model.GitModelObject;
 
 /**
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitModelSynchronize.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitModelSynchronize.java
index 9c12223..c44366a 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitModelSynchronize.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitModelSynchronize.java
@@ -26,14 +26,14 @@
 import org.eclipse.core.runtime.jobs.IJobChangeEvent;
 import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.core.runtime.jobs.JobChangeAdapter;
-import org.eclipse.egit.core.AdapterUtils;
+import org.eclipse.egit.core.internal.AdapterUtils;
+import org.eclipse.egit.core.internal.synchronize.GitResourceVariantTreeSubscriber;
+import org.eclipse.egit.core.internal.synchronize.GitSubscriberMergeContext;
+import org.eclipse.egit.core.internal.synchronize.GitSubscriberResourceMappingContext;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeData;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeDataSet;
 import org.eclipse.egit.core.internal.util.ResourceUtil;
-import org.eclipse.egit.core.synchronize.GitResourceVariantTreeSubscriber;
-import org.eclipse.egit.core.synchronize.GitSubscriberMergeContext;
-import org.eclipse.egit.core.synchronize.GitSubscriberResourceMappingContext;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.ui.internal.JobFamilies;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.Repository;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitModelSynchronizeParticipant.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitModelSynchronizeParticipant.java
index f8937fa..3e5a89b 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitModelSynchronizeParticipant.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitModelSynchronizeParticipant.java
@@ -37,16 +37,16 @@
 import org.eclipse.core.runtime.jobs.IJobChangeEvent;
 import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.core.runtime.jobs.JobChangeAdapter;
-import org.eclipse.egit.core.AdapterUtils;
-import org.eclipse.egit.core.project.GitProjectData;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.core.synchronize.GitResourceVariantTreeSubscriber;
-import org.eclipse.egit.core.synchronize.GitSubscriberMergeContext;
-import org.eclipse.egit.core.synchronize.GitSubscriberResourceMappingContext;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.core.internal.AdapterUtils;
+import org.eclipse.egit.core.internal.project.GitProjectData;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.egit.core.internal.synchronize.GitResourceVariantTreeSubscriber;
+import org.eclipse.egit.core.internal.synchronize.GitSubscriberMergeContext;
+import org.eclipse.egit.core.internal.synchronize.GitSubscriberResourceMappingContext;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeData;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeDataSet;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.synchronize.compare.ComparisonDataSource;
 import org.eclipse.egit.ui.internal.synchronize.compare.GitCompareInput;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitSynchronizeWizard.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitSynchronizeWizard.java
index 7227782..40fe1b0 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitSynchronizeWizard.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitSynchronizeWizard.java
@@ -24,10 +24,10 @@
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.runtime.IAdaptable;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeData;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeDataSet;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.viewers.ISelection;
 import org.eclipse.jface.viewers.IStructuredSelection;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitSynchronizeWizardPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitSynchronizeWizardPage.java
index 946e4d4..489e3e1 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitSynchronizeWizardPage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitSynchronizeWizardPage.java
@@ -25,11 +25,11 @@
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IWorkspaceRoot;
 import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.CommonUtils;
 import org.eclipse.egit.ui.internal.UIIcons;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.dialogs.Dialog;
 import org.eclipse.jface.layout.GridDataFactory;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitTreeCompareNavigator.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitTreeCompareNavigator.java
index 2183f52..4e68e48 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitTreeCompareNavigator.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/GitTreeCompareNavigator.java
@@ -15,7 +15,7 @@
 import org.eclipse.compare.INavigatable;
 import org.eclipse.core.runtime.jobs.IJobManager;
 import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.egit.ui.JobFamilies;
+import org.eclipse.egit.ui.internal.JobFamilies;
 
 /**
  * Wraps given {@link CompareNavigator} and waits for add to index, remove from
@@ -62,7 +62,7 @@
 		try {
 			manager.join(JobFamilies.ADD_TO_INDEX, null);
 			manager.join(JobFamilies.REMOVE_FROM_INDEX, null);
-			manager.join(org.eclipse.egit.core.JobFamilies.REPOSITORY_CHANGED, null);
+			manager.join(org.eclipse.egit.core.internal.JobFamilies.REPOSITORY_CHANGED, null);
 		} catch (InterruptedException e) {
 			// ignore
 		}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/SynchronizeFetchJob.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/SynchronizeFetchJob.java
index 4534cbd..ad87851 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/SynchronizeFetchJob.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/SynchronizeFetchJob.java
@@ -15,10 +15,10 @@
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.SubMonitor;
 import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeData;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeDataSet;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.credentials.EGitCredentialsProvider;
 import org.eclipse.egit.ui.internal.fetch.FetchOperationUI;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/action/GitOpenInCompareAction.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/action/GitOpenInCompareAction.java
index f88222c..54cd9f1 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/action/GitOpenInCompareAction.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/action/GitOpenInCompareAction.java
@@ -19,8 +19,8 @@
 import org.eclipse.compare.ITypedElement;
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.runtime.IPath;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
 import org.eclipse.egit.core.internal.util.ResourceUtil;
-import org.eclipse.egit.core.project.RepositoryMapping;
 import org.eclipse.egit.ui.internal.CompareUtils;
 import org.eclipse.egit.ui.internal.GitCompareFileRevisionEditorInput;
 import org.eclipse.egit.ui.internal.synchronize.compare.LocalNonWorkspaceTypedElement;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/action/PullAction.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/action/PullAction.java
index 28585fb..8c7844b 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/action/PullAction.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/action/PullAction.java
@@ -16,8 +16,8 @@
 
 import org.eclipse.compare.structuremergeviewer.IDiffElement;
 import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeData;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeDataSet;
 import org.eclipse.egit.ui.internal.pull.PullOperationUI;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.team.ui.synchronize.ISynchronizePageConfiguration;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/action/PushAction.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/action/PushAction.java
index c5c7485..012ab47 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/action/PushAction.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/action/PushAction.java
@@ -16,10 +16,10 @@
 
 import org.eclipse.compare.structuremergeviewer.IDiffElement;
 import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
-import org.eclipse.egit.ui.Activator;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeData;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeDataSet;
+import org.eclipse.egit.ui.internal.Activator;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.credentials.EGitCredentialsProvider;
 import org.eclipse.egit.ui.internal.push.PushOperationUI;
 import org.eclipse.jgit.lib.Repository;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/compare/LocalNonWorkspaceTypedElement.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/compare/LocalNonWorkspaceTypedElement.java
index 368af1b..79fb9b1 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/compare/LocalNonWorkspaceTypedElement.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/compare/LocalNonWorkspaceTypedElement.java
@@ -28,8 +28,8 @@
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Platform;
 import org.eclipse.core.runtime.Status;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jgit.events.IndexChangedEvent;
 import org.eclipse.jgit.util.FileUtils;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitChangeSetContentProvider.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitChangeSetContentProvider.java
index 7fdae0c..309cc8c 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitChangeSetContentProvider.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitChangeSetContentProvider.java
@@ -18,10 +18,10 @@
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IAdaptable;
 import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.synchronize.GitResourceVariantTreeSubscriber;
-import org.eclipse.egit.core.synchronize.GitSubscriberMergeContext;
-import org.eclipse.egit.core.synchronize.GitSubscriberResourceMappingContext;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.synchronize.GitResourceVariantTreeSubscriber;
+import org.eclipse.egit.core.internal.synchronize.GitSubscriberMergeContext;
+import org.eclipse.egit.core.internal.synchronize.GitSubscriberResourceMappingContext;
 import org.eclipse.egit.ui.internal.synchronize.GitChangeSetModelProvider;
 import org.eclipse.egit.ui.internal.synchronize.model.GitModelBlob;
 import org.eclipse.egit.ui.internal.synchronize.model.GitModelCache;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitChangeSetLabelProvider.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitChangeSetLabelProvider.java
index cb74041..6fff70e 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitChangeSetLabelProvider.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitChangeSetLabelProvider.java
@@ -14,9 +14,9 @@
 import java.util.Map;
 import java.util.Map.Entry;
 
-import org.eclipse.egit.core.synchronize.GitCommitsModelCache.Commit;
-import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.core.internal.synchronize.GitCommitsModelCache.Commit;
 import org.eclipse.egit.ui.internal.GitLabelProvider;
+import org.eclipse.egit.ui.internal.UIPreferences;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.synchronize.GitChangeSetModelProvider;
 import org.eclipse.egit.ui.internal.synchronize.model.GitModelCommit;
@@ -44,7 +44,7 @@
 	public static final String BINDING_CHANGESET_DATE = "{date}"; //$NON-NLS-1$
 
 
-	private IPreferenceStore store = org.eclipse.egit.ui.Activator.getDefault().getPreferenceStore();
+	private IPreferenceStore store = org.eclipse.egit.ui.internal.Activator.getDefault().getPreferenceStore();
 
 	private final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat(
 			store.getString(UIPreferences.DATE_FORMAT));
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitChangeSetSorter.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitChangeSetSorter.java
index a87eded..163d7ab 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitChangeSetSorter.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/mapping/GitChangeSetSorter.java
@@ -8,7 +8,7 @@
  *******************************************************************************/
 package org.eclipse.egit.ui.internal.synchronize.mapping;
 
-import org.eclipse.egit.core.synchronize.GitCommitsModelCache.Commit;
+import org.eclipse.egit.core.internal.synchronize.GitCommitsModelCache.Commit;
 import org.eclipse.egit.ui.internal.synchronize.model.GitModelBlob;
 import org.eclipse.egit.ui.internal.synchronize.model.GitModelCache;
 import org.eclipse.egit.ui.internal.synchronize.model.GitModelCommit;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelBlob.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelBlob.java
index 0a78e97..9981ce3 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelBlob.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelBlob.java
@@ -25,8 +25,8 @@
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.synchronize.GitCommitsModelCache.Change;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.synchronize.GitCommitsModelCache.Change;
 import org.eclipse.egit.ui.internal.synchronize.compare.ComparisonDataSource;
 import org.eclipse.egit.ui.internal.synchronize.compare.GitCompareInput;
 import org.eclipse.jgit.lib.AbbreviatedObjectId;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelCache.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelCache.java
index 56dd3ff..b06ebc6 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelCache.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelCache.java
@@ -13,7 +13,7 @@
 import org.eclipse.compare.structuremergeviewer.Differencer;
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.core.synchronize.GitCommitsModelCache.Change;
+import org.eclipse.egit.core.internal.synchronize.GitCommitsModelCache.Change;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.synchronize.model.TreeBuilder.FileModelFactory;
 import org.eclipse.egit.ui.internal.synchronize.model.TreeBuilder.TreeModelFactory;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelCacheFile.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelCacheFile.java
index ed91379..b655a51 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelCacheFile.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelCacheFile.java
@@ -10,7 +10,7 @@
 
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.runtime.IPath;
-import org.eclipse.egit.core.synchronize.GitCommitsModelCache.Change;
+import org.eclipse.egit.core.internal.synchronize.GitCommitsModelCache.Change;
 import org.eclipse.egit.ui.internal.synchronize.compare.ComparisonDataSource;
 import org.eclipse.egit.ui.internal.synchronize.compare.GitCacheCompareInput;
 import org.eclipse.egit.ui.internal.synchronize.compare.GitCompareInput;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelCommit.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelCommit.java
index 91ee7df..e294efb 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelCommit.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelCommit.java
@@ -12,8 +12,8 @@
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.core.synchronize.GitCommitsModelCache.Change;
-import org.eclipse.egit.core.synchronize.GitCommitsModelCache.Commit;
+import org.eclipse.egit.core.internal.synchronize.GitCommitsModelCache.Change;
+import org.eclipse.egit.core.internal.synchronize.GitCommitsModelCache.Commit;
 import org.eclipse.egit.ui.internal.synchronize.model.TreeBuilder.FileModelFactory;
 import org.eclipse.egit.ui.internal.synchronize.model.TreeBuilder.TreeModelFactory;
 import org.eclipse.jgit.lib.Repository;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelObject.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelObject.java
index cbfffea..0bcb8cd 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelObject.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelObject.java
@@ -12,7 +12,7 @@
 
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.PlatformObject;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeData;
 import org.eclipse.jgit.errors.MissingObjectException;
 
 /**
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelRepository.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelRepository.java
index abc1c22..ab64b18 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelRepository.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelRepository.java
@@ -19,13 +19,13 @@
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.core.synchronize.GitCommitsModelCache;
-import org.eclipse.egit.core.synchronize.GitCommitsModelCache.Change;
-import org.eclipse.egit.core.synchronize.GitCommitsModelCache.Commit;
-import org.eclipse.egit.core.synchronize.StagedChangeCache;
-import org.eclipse.egit.core.synchronize.WorkingTreeChangeCache;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.synchronize.GitCommitsModelCache;
+import org.eclipse.egit.core.internal.synchronize.StagedChangeCache;
+import org.eclipse.egit.core.internal.synchronize.WorkingTreeChangeCache;
+import org.eclipse.egit.core.internal.synchronize.GitCommitsModelCache.Change;
+import org.eclipse.egit.core.internal.synchronize.GitCommitsModelCache.Commit;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeData;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.revwalk.RevCommit;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelRoot.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelRoot.java
index 86bf8f4..e06aa18 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelRoot.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelRoot.java
@@ -12,9 +12,9 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import org.eclipse.egit.core.Activator;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeData;
-import org.eclipse.egit.core.synchronize.dto.GitSynchronizeDataSet;
+import org.eclipse.egit.core.internal.Activator;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeData;
+import org.eclipse.egit.core.internal.synchronize.dto.GitSynchronizeDataSet;
 
 /**
  * Root of all model objects.
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelWorkingFile.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelWorkingFile.java
index a9aeb7e..2a79423 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelWorkingFile.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelWorkingFile.java
@@ -9,7 +9,7 @@
 package org.eclipse.egit.ui.internal.synchronize.model;
 
 import org.eclipse.core.runtime.IPath;
-import org.eclipse.egit.core.synchronize.GitCommitsModelCache.Change;
+import org.eclipse.egit.core.internal.synchronize.GitCommitsModelCache.Change;
 import org.eclipse.jgit.lib.Repository;
 
 /**
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelWorkingTree.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelWorkingTree.java
index ae33d90..1a479d0 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelWorkingTree.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/GitModelWorkingTree.java
@@ -14,7 +14,7 @@
 
 import org.eclipse.compare.structuremergeviewer.Differencer;
 import org.eclipse.core.runtime.IPath;
-import org.eclipse.egit.core.synchronize.GitCommitsModelCache.Change;
+import org.eclipse.egit.core.internal.synchronize.GitCommitsModelCache.Change;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.egit.ui.internal.synchronize.model.TreeBuilder.FileModelFactory;
 import org.eclipse.jgit.lib.Repository;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/TreeBuilder.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/TreeBuilder.java
index aefa033..7e231d3 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/TreeBuilder.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/synchronize/model/TreeBuilder.java
@@ -15,7 +15,7 @@
 
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.Path;
-import org.eclipse.egit.core.synchronize.GitCommitsModelCache.Change;
+import org.eclipse.egit.core.internal.synchronize.GitCommitsModelCache.Change;
 import org.eclipse.jgit.lib.Repository;
 
 /**
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/trace/GitTraceLocation.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/trace/GitTraceLocation.java
index a1443ae..ee93183 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/trace/GitTraceLocation.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/trace/GitTraceLocation.java
@@ -10,7 +10,7 @@
  *******************************************************************************/
 package org.eclipse.egit.ui.internal.trace;
 
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.osgi.service.debug.DebugOptions;
 import org.eclipse.osgi.service.debug.DebugTrace;
 
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/uitext.properties b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/uitext.properties
new file mode 100644
index 0000000..8d24014
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/uitext.properties
@@ -0,0 +1,1673 @@
+###############################################################################
+# Copyright (c) 2005, 2013 Shawn Pearce and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#    Shawn Pearce - initial implementation
+#    Daniel Megert <daniel_megert@ch.ibm.com> - Escaped single quotes where needed
+#                                             - Removed unused entry
+#                                             - Added context menu to the Commit Editor's header text
+#    Markus Keller <markus_keller@ch.ibm.com> - Show the repository name in the title of the Pull Result dialog
+#    Daniel Megert <daniel_megert@ch.ibm.com> - Use correct syntax when a single ref was updated
+#    Gunnar Wagenknecht <gunnar@wagenknecht.org>
+###############################################################################
+AbortRebaseCommand_CancelDialogMessage=The abort operation was canceled
+AbortRebaseCommand_JobName=Aborting Rebase
+AbstractHistoryCommanndHandler_CouldNotGetRepositoryMessage=Could not get the repository from the history view
+AbstractHistoryCommanndHandler_NoInputMessage=Could not get the current input from the history view
+AbstractRebaseCommand_DialogTitle=Action Canceled
+AbstractReflogCommandHandler_NoInput=Could not get the current input from the Reflog View
+Activator_DefaultRepoFolderIsFile=The location {0} of the default repository folder is already used by a file
+Activator_DefaultRepoFolderNotCreated=Default repository folder {0} could not be created
+Activator_refreshingProjects=Refreshing Git managed projects
+Activator_refreshJobName=Git Repository Refresh
+Activator_repoScanJobName=Git Repository Change Scanner
+Activator_scanError=An error occurred while scanning for changes. Scanning aborted
+Activator_scanningRepositories=Scanning Git repositories for changes
+Activator_refreshFailed=Failed to refresh projects from index changes
+AddConfigEntryDialog_AddConfigTitle=Add a configuration entry
+AddConfigEntryDialog_ConfigKeyTooltip=Use "." to separate section/subsection/name, e.g. "core.bare", "remote.origin.url"
+AddConfigEntryDialog_DialogMessage=Please enter a key, e.g. "user.name" and a value
+AddConfigEntryDialog_EnterValueMessage=Please enter a value
+AddConfigEntryDialog_KeyComponentsMessage=The key must have two or three components separated by "."
+AddConfigEntryDialog_KeyLabel=&Key
+AddConfigEntryDialog_MustEnterKeyMessage=Please enter a key
+AddConfigEntryDialog_ValueLabel=&Value
+AddSubmoduleWizard_WindowTitle=Add Submodule
+AddToIndexAction_addingFiles=Adding Files to Git Index
+AddToIndexCommand_addingFilesFailed=Adding files failed
+RemoveFromIndexAction_removingFiles=Removing file from Git Index
+BlameInformationControl_Author=Author: {0} <{1}> {2}
+BlameInformationControl_Commit=Commit {0}
+BlameInformationControl_Committer=Committer: {0} <{1}> {2}
+AssumeUnchanged_assumeUnchanged=Assume Unchanged
+AssumeUnchanged_noAssumeUnchanged=No Assume Unchanged
+WizardProjectsImportPage_ImportProjectsTitle=Import Projects
+WizardProjectsImportPage_ImportProjectsDescription=Import projects from a Git repository
+WizardProjectsImportPage_ProjectsListTitle=&Projects:
+WizardProjectsImportPage_selectAll = &Select All
+WizardProjectsImportPage_deselectAll = &Deselect All
+WizardProjectsImportPage_SearchingMessage = Searching for projects
+WizardProjectsImportPage_ProcessingMessage = Processing results
+WizardProjectsImportPage_projectsInWorkspace = Some or all projects can not be imported because they already exist in the workspace
+WizardProjectsImportPage_CheckingMessage = Checking: {0}
+WizardProjectsImportPage_CreateProjectsTask = Creating Projects
+WizardProjectsImportPage_filterText = type filter text to filter unselected projects
+
+SecureStoreUtils_writingCredentialsFailed=Writing to secure store failed
+SelectResetTypePage_labelCurrentHead=Current HEAD:
+SelectResetTypePage_labelResettingTo=Resetting to:
+SelectResetTypePage_PageMessage=Select the type of reset to perform
+SelectResetTypePage_PageTitle=Reset {0}
+SelectResetTypePage_tooltipCurrentHead=The current HEAD ref
+SelectResetTypePage_tooltipResettingTo=The ref being reset to
+SharingWizard_windowTitle=Configure Git Repository
+SharingWizard_failed=Failed to initialize Git team provider.
+SharingWizard_MoveProjectActionLabel=Move Project
+ShowBlameHandler_errorMessage=Showing annotations failed
+ShowBlameHandler_JobName=Computing Blame Annotations
+
+GenerateHistoryJob_BuildingListMessage=Building commit list for ''{0}''...
+GenerateHistoryJob_CancelMessage=Reading commit list was canceled for ''{0}''
+GenerateHistoryJob_errorComputingHistory=Cannot compute Git history.
+GenerateHistoryJob_NoCommits=No commits for ''{0}''
+GenerateHistoryJob_taskFoundMultipleCommits=Found {0} commits
+GenerateHistoryJob_taskFoundSingleCommit=Found 1 commit
+GerritConfigurationPage_BranchTooltipHover=Press {0} to see a filtered list of branch names
+GerritConfigurationPage_ConfigureFetchReviewNotes=Fetch will be auto-configured to fetch review notes from Gerrit.
+GerritConfigurationPage_errorBranchName=Branch name is required
+GerritConfigurationPage_groupFetch=Fetch configuration
+GerritConfigurationPage_groupPush=Push configuration
+GerritConfigurationPage_labelDestinationBranch=&Destination branch:
+GerritConfigurationPage_PageDescription=Configure Gerrit Code Review properties for remote ''{0}'' of repository ''{1}''
+GerritConfigurationPage_pushUri=&Push URI
+GerritConfigurationPage_title=Gerrit Configuration
+GerritConfigurationPage_UserLabel=&User:
+
+EGitCredentialsProvider_errorReadingCredentials=Failed reading credentials from secure store
+EGitCredentialsProvider_FailedToClearCredentials=Failed to clear credentials for {0} stored in secure store
+EGitCredentialsProvider_question=Question
+EGitCredentialsProvider_information=Information
+CustomPromptDialog_provide_information_for=Provide information for {0}
+CustomPromptDialog_information_about=Information about {0}
+EgitUiUtils_CouldNotOpenEditorMessage=Could not open editor of type {0}
+ExistingOrNewPage_BrowseRepositoryButton=Br&owse...
+ExistingOrNewPage_CreateButton=&Create Repository
+ExistingOrNewPage_CreateRepositoryButton=Create...
+ExistingOrNewPage_CreationInWorkspaceWarningTooltip=When checked, this wizard will try to find or create a repository in the parent folder hierarchy of the selected projects.\nTypically, newly created projects are located in the Eclipse workspace, thus repositories created this way\nwould also end up in the Eclipse workspace.\nThis is not recommended for several reasons explained in the EGit user guide.
+ExistingOrNewPage_CurrentLocationColumnHeader=Current Location
+ExistingOrNewPage_title=Configure Git Repository
+ExistingOrNewPage_description=Select repository location
+ExistingOrNewPage_DescriptionExternalMode=Select an existing repository or create a new one
+ExistingOrNewPage_ErrorFailedToCreateRepository=Failed to create repository {0}
+ExistingOrNewPage_ErrorFailedToRefreshRepository=Failed to refresh project after creating repository at {0}
+ExistingOrNewPage_ExistingRepositoryLabel=&Repository:
+ExistingOrNewPage_ExistingTargetErrorMessage=Target location for project {0} already exists, can not move project
+ExistingOrNewPage_FailedToDetectRepositoryMessage=Failed to detect which repository to use
+ExistingOrNewPage_FolderWillBeCreatedMessage=Folder {0} does not exist in working directory, will be created
+ExistingOrNewPage_HeaderLocation=Location
+ExistingOrNewPage_HeaderProject=Project
+ExistingOrNewPage_HeaderRepository=Repository
+ExistingOrNewPage_InternalModeCheckbox=&Use or create repository in parent folder of project
+ExistingOrNewPage_NestedProjectErrorMessage=Can not move project {0} to target location {1}, as this location overlaps with location {2}, which contains a .project file
+ExistingOrNewPage_NewLocationTargetHeader=Target Location
+ExistingOrNewPage_NoRepositorySelectedMessage=No repository selected
+ExistingOrNewPage_ProjectNameColumnHeader=Project
+ExistingOrNewPage_RelativePathLabel=&Path within repository:
+ExistingOrNewPage_RepoCreationInWorkspaceCreationWarning=Creation of repositories in the Eclipse workspace is not recommended
+ExistingOrNewPage_SymbolicValueEmptyMapping=<empty repository mapping>
+ExistingOrNewPage_WorkingDirectoryLabel=Working directory:
+ExistingOrNewPage_WrongPathErrorDialogMessage=The selected path is not a child of the repository working tree
+ExistingOrNewPage_WrongPathErrorDialogTitle=Wrong Path
+
+GitCloneSourceProviderExtension_Local=Local
+GitCloneWizard_abortingCloneMsg=A partial or complete clone was already made. Do you want to delete it?
+GitCloneWizard_abortingCloneTitle=Aborting Clone
+GitCloneWizard_title=Clone Git Repository
+GitCloneWizard_jobImportProjects=Importing projects from ''{0}''
+GitCloneWizard_jobName=Cloning from {0}
+GitCloneWizard_failed=Git repository clone failed.
+GitCloneWizard_errorCannotCreate=Cannot create directory {0}.
+GitCloneWizard_MissingNotesMessage=No review has been done yet for the Repository.\nPlease add the fetch refspec "refs/notes/review:refs/notes/review" later on.
+GitCloneWizard_MissingNotesTitle=Missing Review Notes
+GitDecoratorPreferencePage_bindingRepositoryNameFlag=Name and state of the repository (the default state will not be shown)
+GitDecoratorPreferencePage_iconsShowDirty=Dirty resources
+GitDocument_errorLoadCommit=Could not load commit {0} for {1} corresponding to {2} in {3}
+GitDocument_errorLoadTree=Could not load tree {0} for {1} corresponding to {2} in {3}
+GitDocument_errorRefreshQuickdiff=Failed to refresh Quick Diff
+GitDocument_errorResolveQuickdiff=Could not resolve Quick Diff baseline {0} corresponding to {1} in {2}
+GitHistoryPage_AllChangesInFolderHint=All changes of this resource's parent folder and its children
+GitHistoryPage_AllChangesInProjectHint=All changes of this resource's project and its children
+GitHistoryPage_AllChangesInRepoHint=All changes in the repository containing this resource
+GitHistoryPage_AllChangesOfResourceHint=Changes of this resource and its children only
+GitHistoryPage_AllInParentMenuLabel=All Changes in Parent &Folder
+GitHistoryPage_AllInParentTooltip=Show all changes in parent folder of the selected resource
+GitHistoryPage_AllInProjectMenuLabel=All Changes in &Project
+GitHistoryPage_AllInProjectTooltip=Show all changes in project containing the selected resource
+GitHistoryPage_AllInRepoMenuLabel=All Changes in &Repository
+GitHistoryPage_AllInRepoTooltip=Show all changes in repository containing the selected resource
+GitHistoryPage_AllOfResourceMenuLabel=All &Changes of Resource
+GitHistoryPage_AllOfResourceTooltip=Show all changes of selected resource and its children
+GitHistoryPage_CheckoutMenuLabel=&Checkout
+GitHistoryPage_CheckoutMenuLabel2=&Checkout...
+GitHistoryPage_CompareModeMenuLabel=Compare &Mode
+GitHistoryPage_ReuseCompareEditorMenuLabel=Reuse Compare &Editor
+GitHistoryPage_CompareWithCurrentHeadMenu=Compare with &HEAD
+GitHistoryPage_CompareWithEachOtherMenuLabel=Compare with &Each Other
+GitHistoryPage_CompareWithWorkingTreeMenuMenuLabel=Compare with &Workspace
+GitHistoryPage_CreateBranchMenuLabel=Create &Branch...
+GitHistoryPage_CreatePatchMenuLabel=Create &Patch...
+GitHistoryPage_CreateTagMenuLabel=Create &Tag...
+GitHistoryPage_cherryPickMenuItem=C&herry Pick
+GitHistoryPage_compareMode=Compare Mode
+GitHistoryPage_showAllBranches=Show All Branches and Tags
+GitHistoryPage_errorLookingUpPath=IO error looking up path {0} in {1}.
+GitHistoryPage_errorParsingHead=Cannot parse HEAD in: {0}
+GitHistoryPage_errorReadingAdditionalRefs=Cannot read additional references for repository {0}
+GitHistoryPage_errorSettingStartPoints=Cannot set start points for repository {0}
+GitHistoryPage_fileNotFound=File not Found
+GitHistoryPage_notContainedInCommits=File {0} is not contained in the commits: {1}
+GitHistoryPage_FileNotInCommit={0} not in {1}
+GitHistoryPage_FileOrFolderPartOfGitDirMessage=File or folder {0} is part of the repository''s Git directory
+GitHistoryPage_FileType=File
+GitHistoryPage_FindMenuLabel=Find &Toolbar
+GitHistoryPage_FindTooltip=Show Find Toolbar
+GitHistoryPage_FolderType=Folder
+GitHistoryPage_MultiResourcesType={0} resources
+GitHistoryPage_NoInputMessage=No input
+GitHistoryPage_openFailed=Opening Editor Failed
+GitHistoryPage_OpenInTextEditorLabel=Open in Text &Editor
+GitHistoryPage_OpenMenuLabel=&Open
+GitHistoryPage_PreferencesLink=<a>Preferences...</a>
+GitHistoryPage_ProjectType=Project
+GitHistoryPage_QuickdiffMenuLabel=&Quick Diff
+GitHistoryPage_RefreshMenuLabel=&Refresh
+GitHistoryPage_RepositoryNamePattern=Repository: {0}
+GitHistoryPage_ResetBaselineToHeadMenuLabel=Reset Baseline to &Current Revision (HEAD)
+GitHistoryPage_ResetBaselineToParentOfHeadMenuLabel=Reset Baseline to &Previous Revision (HEAD^)
+GitHistoryPage_ResetHardMenuLabel=&Hard (HEAD, Index, and Working Directory)
+GitHistoryPage_ResetMenuLabel=&Reset
+GitHistoryPage_ResetMixedMenuLabel=&Mixed (HEAD and Index)
+GitHistoryPage_ResetSoftMenuLabel=&Soft (HEAD Only)
+GitHistoryPage_revertMenuItem=Revert Commit
+GitHistoryPage_mergeMenuItem=Merge
+GitHistoryPage_rebaseMenuItem=Rebase on Top of
+GitHistoryPage_SetAsBaselineMenuLabel=&Set as Baseline
+GitHistoryPage_ShowAdditionalRefsMenuLabel=&Additional Refs
+GitHistoryPage_ShowAllBranchesMenuLabel=All &Branches and Tags
+GitHistoryPage_FollowRenames=&Follow Renames
+GitHistoryPage_FilterSubMenuLabel=&Filter
+GitHistoryPage_IncompleteListTooltip=Not all commits are shown, the limit may be exceeded or the job building the list may have been aborted
+GitHistoryPage_InRevisionCommentSubMenuLabel=&In Revision Comment
+GitHistoryPage_ListIncompleteWarningMessage=The list is incomplete
+GitHistoryPage_pushCommit=Push Commit...
+GitHistoryPage_ShowSubMenuLabel=&Show
+GitHistoryPage_toggleEmailAddresses=&E-mail Addresses
+GitPreferenceRoot_automaticallyEnableChangesetModel=Automatically enable commit &grouping in Git synchronizations
+GitPreferenceRoot_BlameGroupHeader=Blame Annotations
+GitPreferenceRoot_BlameIgnoreWhitespaceLabel=Ignore whitespace changes
+GitPreferenceRoot_fetchBeforeSynchronization=Always launch fetch before synchronization
+GitPreferenceRoot_CloningRepoGroupHeader=Cloning repositories
+GitPreferenceRoot_DefaultRepoFolderLabel=Default repository &folder:
+GitPreferenceRoot_DefaultRepoFolderTooltip=This folder will be suggested as parent folder when cloning a remote repository
+GitPreferenceRoot_DefaultRepoFolderVariableButton=&Variable...
+GitPreferenceRoot_HistoryGroupHeader=History view
+GitPreferenceRoot_MergeGroupHeader=Merge
+GitPreferenceRoot_MergeMode_0_Label=Prompt when starting tool
+GitPreferenceRoot_MergeMode_1_Label=Workspace (pre-merged by Git)
+GitPreferenceRoot_MergeMode_2_Label=Last HEAD (unmerged)
+GitPreferenceRoot_MergeModeLabel=&Merge tool content:
+GitPreferenceRoot_MergeModeTooltip=Determines which content to be displayed on the left side of the merge tool
+GitPreferenceRoot_RemoteConnectionsGroupHeader=Remote connections
+GitPreferenceRoot_RepoChangeScannerGroupHeader=Automatic refresh
+GitPreferenceRoot_SecureStoreGroupLabel=Secure Store
+GitPreferenceRoot_SecureStoreUseByDefault=Store credentials in secure store by default
+GitPreferenceRoot_SynchronizeView=Synchronize view
+GitProjectPropertyPage_LabelBranch=Branch:
+GitProjectPropertyPage_LabelGitDir=Git directory:
+GitProjectPropertyPage_LabelId=HEAD:
+GitProjectPropertyPage_LabelState=Current state:
+GitProjectPropertyPage_LabelWorkdir=Working directory:
+GitProjectPropertyPage_UnableToGetCommit=Unable to load commit {0}
+GitProjectPropertyPage_ValueEmptyRepository=None (empty repository)
+GitProjectPropertyPage_ValueUnbornBranch=None (unborn branch)
+GitProjectsImportPage_NoProjectsMessage=No projects found
+GitProjectsImportPage_SearchForNestedProjects=Searc&h for nested projects
+
+CleanRepositoryPage_cleanDirs=Clean selected untracked files and directories
+CleanRepositoryPage_cleanFiles=Clean selected untracked files
+CleanRepositoryPage_cleaningItems=Cleaning selected items...
+CleanRepositoryPage_findingItems=Finding items to clean...
+CleanRepositoryPage_includeIgnored=Include ignored resources
+CleanRepositoryPage_message=Select items to clean
+CleanRepositoryPage_title=Clean Repository
+ClearCredentialsCommand_clearingCredentialsFailed=Clearing credentials failed.
+CheckoutConflictDialog_conflictMessage=The files shown below have uncommitted changes which would be lost by the selected operation.\n\nEither commit the changes to the repository or discard the changes by resetting the current branch.
+CheckoutDialog_Message=Select a ref and choose action to execute
+CheckoutDialog_OkCheckout=&Checkout
+CheckoutDialog_Title=Checkout a ref or work with branches
+CheckoutDialog_WindowTitle=Branches
+CheckoutHandler_SelectBranchMessage=There is more than one branch for this commit. Please select the branch you want to check out.
+CheckoutHandler_SelectBranchTitle=Select a Branch for Checkout
+CherryPickHandler_NoCherryPickPerformedMessage=The change has already been included
+CherryPickHandler_NoCherryPickPerformedTitle=No cherry pick performed
+CherryPickHandler_CherryPickConflictsMessage=Cherry pick could not be completed automatically because of conflicts. Please resolve and commit.
+CherryPickHandler_CherryPickConflictsTitle=Cherry Pick Conflicts
+CherryPickHandler_CherryPickFailedMessage=Cherry pick failed
+CherryPickHandler_CouldNotDeleteFile=Could not delete file
+CherryPickHandler_ErrorMsgTemplate={0} {1}
+CherryPickHandler_IndexDirty=Index is dirty
+CherryPickHandler_JobName=Cherry Picking Commit {0}
+CherryPickHandler_ConfirmMessage=Are you sure you want to cherry pick commit ''{0}'' onto branch ''{1}''?
+CherryPickHandler_ConfirmTitle=Cherry Pick Commit
+CherryPickHandler_unknown=unknown
+CherryPickHandler_WorktreeDirty=File is modified
+CherryPickOperation_Failed=The cherry pick failed
+CherryPickOperation_InternalError=An internal error occurred
+CompareTargetSelectionDialog_CompareButton=&Compare
+CompareTargetSelectionDialog_CompareMessage=Select a branch, tag, or reference to compare the resource with
+CompareTargetSelectionDialog_CompareTitle=Compare ''{0}'' with a Branch, Tag, or Reference
+CompareTargetSelectionDialog_CompareTitleEmptyPath=Compare with a Branch, Tag, or Reference
+CompareTargetSelectionDialog_WindowTitle=Compare
+CompareTreeView_AnalyzingRepositoryTaskText=Analyzing repository
+CompareTreeView_ExpandAllTooltip=Expand all
+CompareTreeView_CollapseAllTooltip=Collapse all
+CompareTreeView_ComparingTwoVersionDescription=Comparing version {0} of {1} with {2}
+CompareTreeView_ComparingWorkspaceVersionDescription=Comparing workspace version of {0} with {1}
+CompareTreeView_EqualFilesTooltip=Show files with equal content
+CompareTreeView_IndexVersionText=Index
+CompareTreeView_ItemNotFoundInVersionMessage={0} not found in {1}
+CompareTreeView_MultipleResourcesHeaderText=Multiple resources
+CompareTreeView_NoDifferencesFoundMessage=No differences found for the current selection and settings
+CompareTreeView_NoInputText=No input
+CompareTreeView_RepositoryRootName=Repository root
+CompareTreeView_WorkspaceVersionText=Workspace
+CompareUtils_errorGettingEncoding=Getting encoding failed
+CompareUtils_errorGettingHeadCommit=Getting HEAD commit failed
+CompareWithIndexAction_FileNotInIndex={0} not in index
+
+RebaseCurrentRefCommand_RebaseCanceledMessage=The rebase operation was canceled
+RebaseCurrentRefCommand_RebaseCanceledTitle=Rebase Canceled
+RebaseCurrentRefCommand_RebasingCurrentJobName=Rebasing Branch {0}
+RebaseCurrentRefCommand_ErrorGettingCurrentBranchMessage=Error getting the branch to rebase
+RebaseResultDialog_Aborted=Rebase was aborted
+RebaseResultDialog_AbortRebaseRadioText=&Abort rebase
+RebaseResultDialog_ActionGroupTitle=Action to perform
+RebaseResultDialog_CommitIdLabel=&Id:
+RebaseResultDialog_CommitMessageLabel=&Message:
+RebaseResultDialog_Conflicting=Rebase was stopped due to {0} conflicting files
+RebaseResultDialog_ConflictListFailureMessage=Error getting the list of conflicts
+RebaseResultDialog_DetailsGroup=Applying commit:
+RebaseResultDialog_DialogTitle=Rebase Result
+RebaseResultDialog_DiffDetailsLabel=&Files with rebase conflicts:
+RebaseResultDialog_DoNothingRadioText=Do nothing (return to the &workbench)
+RebaseResultDialog_FastForward=Rebase advanced HEAD fast-forward
+RebaseResultDialog_Failed=Rebase failed
+RebaseResultDialog_NextSteps=Next steps
+RebaseResultDialog_NextStepsAfterResolveConflicts=When you have resolved the conflicts run:\n- "Rebase > Continue"\n- or "Rebase > Abort"
+RebaseResultDialog_NextStepsDoNothing=- resolve the conflicts\n- then run "Rebase > Continue"\n- or "Rebase > Abort"
+RebaseResultDialog_NothingToCommit=No changes detected.\n\nIf there is nothing left to stage, chances are that something else\nalready introduced the same changes; you might want to skip this patch using "Rebase > Skip".
+RebaseResultDialog_notInWorkspace=<not in workspace>
+RebaseResultDialog_notInWorkspaceMessage=Some conflicting files are not part of the workspace. Open Staging View and launch a text editor to edit each conflicting file.
+RebaseResultDialog_notShared=<not shared>
+RebaseResultDialog_notSharedMessage=Some conflicting files reside in projects not shared with Git. Please share the related projects with Git.
+RebaseResultDialog_SkipCommitButton=&Skip this commit and continue rebasing the next commits
+RebaseResultDialog_StartMergeRadioText=Start Merge &Tool to resolve conflicts
+RebaseResultDialog_StatusLabel=Result status: {0}
+RebaseResultDialog_Stopped=Rebase stopped with conflicts
+RebaseResultDialog_SuccessfullyFinished=Rebase finished successfully
+RebaseResultDialog_ToggleShowButton=Don't show this confirmation dialog again
+RebaseResultDialog_UpToDate=Rebase did nothing, HEAD was already up-to-date
+RebaseTargetSelectionDialog_DialogMessage=Select a branch other than the currently checked out branch
+RebaseTargetSelectionDialog_DialogMessageWithBranch=Select a branch other than the ''{0}'' branch
+RebaseTargetSelectionDialog_DialogTitle=Rebase the currently checked out branch onto another branch
+RebaseTargetSelectionDialog_DialogTitleWithBranch=Rebase the ''{0}'' branch onto another branch
+RebaseTargetSelectionDialog_RebaseButton=&Rebase
+RebaseTargetSelectionDialog_RebaseTitle=Rebase ''{0}''
+RebaseTargetSelectionDialog_RebaseTitleWithBranch=Rebase ''{0}''
+ReplaceTargetSelectionDialog_ReplaceButton=&Replace
+ReplaceTargetSelectionDialog_ReplaceMessage=Select a branch, tag, or reference to replace the resource with
+ReplaceTargetSelectionDialog_ReplaceTitle=Replace ''{0}'' with a Branch, Tag, or Reference
+ReplaceTargetSelectionDialog_ReplaceTitleEmptyPath=Replace with a Branch, Tag, or Reference
+ReplaceTargetSelectionDialog_ReplaceWindowTitle=Replace
+ReplaceWithPreviousActionHandler_NoParentCommitDialogMessage=No previous revision of {0} could be found in the repository.
+ReplaceWithPreviousActionHandler_NoParentCommitDialogTitle=Previous revision not found
+RepositoryAction_errorFindingRepo=Could not find a repository associated with this project
+RepositoryAction_errorFindingRepoTitle=Cannot Find Repository
+RepositoryAction_multiRepoSelection=Cannot perform action on multiple repositories simultaneously.\n\nPlease select items from only one repository.
+RepositoryAction_multiRepoSelectionTitle=Multiple Repositories Selection
+RepositoryCommit_UserAndDate=\ ({0} on {1})
+RepositoryLocationPage_info=Select a location of Git Repositories
+RepositoryLocationPage_title=Select Repository Source
+RepositoryLocationContentProvider_errorProvidingRepoServer=Error on providing repository server infos
+
+RepositoryPropertySource_EditConfigurationTitle=Git Configuration Editor
+RepositoryPropertySource_EffectiveConfigurationAction=Effective Configuration
+RepositoryPropertySource_EffectiveConfigurationCategory=Effective configuration
+RepositoryPropertySource_ErrorHeader=Error
+RepositoryPropertySource_GlobalConfigurationCategory=Global configuration {0}
+RepositoryPropertySource_GlobalConfigurationMenu=Global Configuration
+RepositoryPropertySource_EditConfigButton=Edit...
+RepositoryPropertySource_EditorMessage=Edit the Git Configuration
+RepositoryPropertySource_RepositoryConfigurationButton=Repository Configuration
+RepositoryPropertySource_RepositoryConfigurationCategory=Repository configuration {0}
+RepositoryPropertySource_SelectModeTooltip=Select a configuration to display
+RepositoryPropertySource_SingleValueButton=Single Value
+RepositoryPropertySource_SuppressMultipleValueTooltip=Suppress display of multiple values
+RepositoryPropertySource_SystemConfigurationMenu=System Configuration
+
+RepositoryRemotePropertySource_ErrorHeader=Error
+RepositoryRemotePropertySource_FetchLabel=Remote Fetch Specification
+RepositoryRemotePropertySource_PushLabel=Remote Push Specification
+RepositoryRemotePropertySource_RemoteFetchURL_label=Remote Fetch URL
+RepositoryRemotePropertySource_RemotePushUrl_label=Remote Push URL
+
+RepositorySearchDialog_AddGitRepositories=Add Git Repositories
+RepositorySearchDialog_DeepSearch_button=&Look for nested repositories
+RepositorySearchDialog_RepositoriesFound_message={0} Git repositories found...
+RepositorySearchDialog_ScanningForRepositories_message=Searching
+RepositorySearchDialog_Search=&Search
+RepositorySearchDialog_SearchCriteriaGroup=Search criteria
+RepositorySearchDialog_SearchRecursiveToolTip=If this is checked, subdirectories of already found repositories will be searched recursively
+RepositorySearchDialog_SearchResultGroup=Search results
+RepositorySearchDialog_SearchTitle=Search and select Git repositories on your local file system
+RepositorySearchDialog_SearchTooltip=Performs a search with the current search criteria and updates the search result
+RepositorySearchDialog_SomeDirectoriesHiddenMessage={0} directories are hidden as they have already been added
+RepositorySearchDialog_DirectoryNotFoundMessage=Directory {0} does not exist
+RepositorySearchDialog_browse=&Browse...
+RepositorySearchDialog_CheckAllRepositories=Check All Repositories
+RepositorySearchDialog_directory=&Directory:
+RepositorySearchDialog_EnterDirectoryToolTip=Enter a local file system directory from which to start the search
+RepositorySearchDialog_errorOccurred=Error occurred
+RepositorySearchDialog_NoSearchAvailableMessage=No search results available for current search criteria, click Search button to update the list
+RepositorySearchDialog_NothingFoundMessage=No Git repositories found
+RepositorySearchDialog_searchRepositoriesMessage=Search for local Git repositories on the file system
+RepositorySearchDialog_UncheckAllRepositories=Uncheck All Repositories
+RepositorySelectionPage_BrowseLocalFile=Local File...
+RepositorySelectionPage_sourceSelectionTitle=Source Git Repository
+RepositorySelectionPage_sourceSelectionDescription=Enter the location of the source repository.
+RepositorySelectionPage_destinationSelectionTitle=Destination Git Repository
+RepositorySelectionPage_destinationSelectionDescription=Enter the location of the destination repository.
+RepositorySelectionPage_configuredRemoteChoice=Configured remote repository
+RepositorySelectionPage_errorValidating=Error validating {0}
+RepositorySelectionPage_uriChoice=Custom URI
+RepositorySelectionPage_groupLocation=Location
+RepositorySelectionPage_groupAuthentication=Authentication
+RepositorySelectionPage_groupConnection=Connection
+RepositorySelectionPage_promptURI=UR&I
+RepositorySelectionPage_promptHost=&Host
+RepositorySelectionPage_promptPath=&Repository path
+RepositorySelectionPage_promptUser=&User
+RepositorySelectionPage_promptPassword=&Password
+RepositorySelectionPage_promptScheme=Protoco&l
+RepositorySelectionPage_promptPort=Por&t
+RepositorySelectionPage_fieldRequired={0} required for {1} protocol.
+RepositorySelectionPage_fieldNotSupported={0} not supported on {1} protocol.
+RepositorySelectionPage_fileNotFound={0} does not exist.
+RepositorySelectionPage_internalError=Internal error; consult Eclipse error log.
+RepositorySelectionPage_storeInSecureStore=Store in Secure Store
+RepositorySelectionPage_tip_file=Local repository
+RepositorySelectionPage_tip_ftp=FTP
+RepositorySelectionPage_tip_git=Git native transfer
+RepositorySelectionPage_tip_http=HTTP (smart or dumb)
+RepositorySelectionPage_tip_https=Secure HTTP (smart or dumb)
+RepositorySelectionPage_tip_sftp=Secure FTP
+RepositorySelectionPage_tip_ssh=Git over SSH (also known as git+ssh)
+RepositorySelectionPage_UriMustNotHaveTrailingSpacesMessage=URI must not have trailing spaces
+SoftResetToRevisionAction_softReset=Soft Reset
+SourceBranchPage_repoEmpty=Source Git repository is empty
+SourceBranchPage_title=Branch Selection
+SourceBranchPage_description=Select branches to clone from remote repository. Remote tracking \
+branches will be created to track updates for these branches in the remote repository.
+SourceBranchPage_branchList=Branches &of {0}:
+SourceBranchPage_selectAll=&Select All
+SourceBranchPage_selectNone=&Deselect All
+SourceBranchPage_errorBranchRequired=At least one branch must be selected.
+SourceBranchPage_cannotListBranches=Cannot list the available branches.
+SourceBranchPage_remoteListingCancelled=Operation canceled
+SourceBranchPage_cannotCreateTemp=Couldn't create temporary repository.
+SourceBranchPage_CompositeTransportErrorMessage={0}:\n{1}
+SourceBranchPage_AuthFailMessage={0}:\nInvalid password or missing SSH key.
+
+CloneDestinationPage_title=Local Destination
+CloneDestinationPage_description=Configure the local storage location for {0}.
+CloneDestinationPage_groupDestination=Destination
+CloneDestinationPage_groupConfiguration=Configuration
+CloneDestinationPage_groupProjects=Projects
+CloneDestinationPage_promptDirectory=&Directory
+CloneDestinationPage_promptInitialBranch=Initial branc&h
+CloneDestinationPage_promptRemoteName=Remote na&me
+CloneDestinationPage_browseButton=Bro&wse
+CloneDestinationPage_cloneSubmodulesButton=Clone &submodules
+CloneDestinationPage_DefaultRepoFolderTooltip=You can change the default parent folder in the Git preferences
+CloneDestinationPage_errorDirectoryRequired=Directory is required
+CloneDestinationPage_errorInitialBranchRequired=Initial branch is required
+CloneDestinationPage_errorNotEmptyDir={0} is not an empty directory.
+CloneDestinationPage_errorRemoteNameRequired=Remote name is required
+CloneDestinationPage_importButton=&Import all existing projects after clone finishes
+
+RefContentProposal_blob=blob
+RefContentProposal_branch=branch
+RefContentProposal_by=by
+RefContentProposal_commit=commit
+RefContentProposal_errorReadingObject=Unable to read object {0} for content proposal assistance
+RefContentProposal_tag=tag
+RefContentProposal_trackingBranch=tracking branch
+RefContentProposal_tree=tree
+RefContentProposal_unknownObject=locally unknown object
+ReflogView_DateColumnHeader=Date
+ReflogView_ErrorOnOpenCommit=Error opening commit
+ReflogView_MessageColumnHeader=Reflog Message
+ReflogView_CommitColumnHeader=Commit
+ReflogView_CommitMessageColumnHeader=Commit Message
+RefSelectionDialog_Messsage=Select a branch to show the reflog for
+RefSelectionDialog_Title=Reflog Branch Selection
+RefSpecDialog_AutoSuggestCheckbox=&Automatically suggest a name for the remote tracking branch
+RefSpecDialog_DestinationFetchLabel=&Tracking branch:
+RefSpecDialog_DestinationPushLabel=&Remote branch:
+RefSpecDialog_FetchMessage=Fetch uses the content of a branch or tag of the remote repository as source and updates a tracking branch of the local repository (the target)
+RefSpecDialog_FetchTitle=Create or Edit a Refspec for Fetch
+RefSpecDialog_ForceUpdateCheckbox=&Force update
+RefSpecDialog_GettingRemoteRefsMonitorMessage=Getting remote refs...
+RefSpecDialog_MissingDataMessage=Please provide both a source and destination
+RefSpecDialog_PushMessage=Push uses the content of a branch or tag of the local repository as source and updates a branch of the remote repository (the target)
+RefSpecDialog_PushTitle=Create or Edit a Refspec for Push
+RefSpecDialog_SourceBranchFetchLabel=&Remote branch or tag:
+RefSpecDialog_SourceBranchPushLabel=&Local branch:
+RefSpecDialog_SpecificationLabel=&Specification:
+RefSpecDialog_WindowTitle=Create or Edit a Refspec
+RefSpecPanel_clickToChange=[Click to change]
+RefSpecPanel_columnDst=Destination Ref
+RefSpecPanel_columnForce=Force Update
+RefSpecPanel_columnMode=Mode
+RefSpecPanel_columnRemove=Remove
+RefSpecPanel_columnSrc=Source Ref
+RefSpecPanel_creationButton=Add Spec
+RefSpecPanel_creationButtonDescription=Add this create/update specification to set of {0} specifications.
+RefSpecPanel_creationDst=Destination ref:
+RefSpecPanel_creationGroup=Add create/update specification
+RefSpecPanel_creationSrc=Source ref:
+RefSpecPanel_deletionButton=Add spec
+RefSpecPanel_deletionButtonDescription=Add this delete specification to set of push specifications.
+RefSpecPanel_deletionGroup=Add delete ref specification
+RefSpecPanel_deletionRef=Remote ref to delete:
+RefSpecPanel_dstFetchDescription=Local destination ref(s) to fetch to - create or update.
+RefSpecPanel_dstPushDescription=Remote destination ref(s) to push to - create or update.
+RefSpecPanel_dstDeletionDescription=Remote ref to delete.
+RefSpecPanel_fetch=fetch
+RefSpecPanel_fetchTitle=Fetch
+RefSpecPanel_forceAll=Force Update All Specs
+RefSpecPanel_forceAllDescription=Set force update setting to all specifications.
+RefSpecPanel_forceDeleteDescription=Delete specification is always unconditional.
+RefSpecPanel_forceFalseDescription=Allow only fast-forward update: old object must merge into new object.
+RefSpecPanel_forceTrueDescription=Allow non-fast-forward update: old object doesn't have to merge to new object.
+RefSpecPanel_modeDelete=Delete
+RefSpecPanel_modeDeleteDescription=This is a delete specification.
+RefSpecPanel_modeUpdate=Update
+RefSpecPanel_modeUpdateDescription=This is a create/update specification.
+RefSpecPanel_predefinedAll=Add All Branches Spec
+RefSpecPanel_predefinedAllDescription=Add specification covering all branches.
+RefSpecPanel_predefinedConfigured=Add Configured {0} Specs
+RefSpecPanel_predefinedConfiguredDescription=Add previously configured specifications for this configured remote (if available).
+RefSpecPanel_predefinedGroup=Add predefined specification
+RefSpecPanel_predefinedTags=Add All Tags Spec
+RefSpecPanel_predefinedTagsDescription=Add specification covering all tags.
+RefSpecPanel_push=push
+RefSpecPanel_pushTitle=Push
+RefSpecPanel_refChooseSome=choose/some/ref
+RefSpecPanel_refChooseSomeWildcard=choose/some/ref/*
+RefSpecPanel_refChooseRemoteName=choose_remote_name
+RefSpecPanel_removeAll=Remove All Specs
+RefSpecPanel_removeAllDescription=Remove all specifications.
+RefSpecPanel_removeDescription=Click to remove this specification.
+RefSpecPanel_specifications=Specifications for {0}
+RefSpecPanel_srcFetchDescription=Remote source ref(s) to fetch from.
+RefSpecPanel_srcPushDescription=Local source ref(s) to push from.
+RefSpecPanel_srcDeleteDescription=Delete specification always has an empty source ref.
+RefSpecPanel_validationDstInvalidExpression={0} is not a valid ref expression for destination.
+RefSpecPanel_validationDstRequired=Destination ref is required.
+RefSpecPanel_validationRefDeleteRequired=Ref name to delete is required.
+RefSpecPanel_validationRefDeleteWildcard=Delete ref cannot be a wildcard.
+RefSpecPanel_validationRefInvalidExpression={0} is not a valid ref expression.
+RefSpecPanel_validationRefInvalidLocal={0} is not a valid ref in local repository.
+RefSpecPanel_validationRefNonExistingRemote={0} does not exist in remote repository.
+RefSpecPanel_validationRefNonExistingRemoteDelete={0} already does not exist in remote repository.
+RefSpecPanel_validationRefNonMatchingLocal={0} does not match any ref in local repository.
+RefSpecPanel_validationRefNonMatchingRemote={0} does not match any ref in remote repository.
+RefSpecPanel_validationSpecificationsOverlappingDestination=Two or more specifications point to {0} (the same destination).
+RefSpecPanel_validationSrcUpdateRequired=Source ref is required for update/create specification.
+RefSpecPanel_validationWildcardInconsistent=Wildcard must be set either on both source and destination or on none of them.
+
+RefSpecPage_descriptionFetch=Select refs to fetch.
+RefSpecPage_descriptionPush=Select refs to push.
+RefSpecPage_errorDontMatchSrc=Specifications don't match any existing refs in source repository.
+RefSpecPage_errorTransportDialogMessage=Cannot get remote repository refs.
+RefSpecPage_errorTransportDialogTitle=Transport Error
+RefSpecPage_operationCancelled=Operation canceled.
+RefSpecPage_saveSpecifications=Save specifications in ''{0}'' configuration
+RefSpecPage_titleFetch=Fetch Ref Specifications
+RefSpecPage_titlePush=Push Ref Specifications
+RefSpecPage_annotatedTagsGroup=Annotated tags fetching strategy
+RefSpecPage_annotatedTagsAutoFollow=Automatically follow tags if we fetch the thing they point at
+RefSpecPage_annotatedTagsFetchTags=Always fetch tags, even if we do not have the thing it points at
+RefSpecPage_annotatedTagsNoTags=Never fetch tags, even if we have the thing it points at
+
+QuickDiff_failedLoading=Quick diff failed to obtain file data.
+
+ResetAction_errorResettingHead=Cannot reset HEAD now
+ResetAction_repositoryState=Repository state: {0}
+ResetAction_reset=Resetting to {0}
+ResetCommand_ResetFailureMessage=Reset failed
+ResetCommand_WizardTitle=Reset
+ResetQuickdiffBaselineHandler_NoTargetMessage=No reset target provided
+ResetTargetSelectionDialog_ResetButton=&Reset
+ResetTargetSelectionDialog_ResetConfirmQuestion=Resetting will overwrite any changes in your working directory.\n\nDo you want to continue?
+ResetTargetSelectionDialog_ResetQuestion=Confirm Reset
+ResetTargetSelectionDialog_ResetTitle=Reset: {0}
+ResetTargetSelectionDialog_ResetTypeGroup=Reset type
+ResetTargetSelectionDialog_ResetTypeHardButton=&Hard (HEAD, index, and working directory updated)
+ResetTargetSelectionDialog_ResetTypeMixedButton=&Mixed (HEAD and index updated)
+ResetTargetSelectionDialog_ResetTypeSoftButton=&Soft (HEAD updated)
+ResetTargetSelectionDialog_ResetTypeHEADHardButton=&Hard (index and working directory updated)
+ResetTargetSelectionDialog_ResetTypeHEADMixedButton=&Mixed (index updated)
+ResetTargetSelectionDialog_SelectBranchForResetMessage=Select a branch to reset the current branch to
+ResetTargetSelectionDialog_WindowTitle=Reset
+ResourceHistory_MaxNumCommitsInList=Maximum number of commits to &show:
+ResourceHistory_ShowTagSequence=&Tag sequence
+ResourceHistory_toggleRelativeDate=Relative &Dates
+ResourceHistory_toggleShowNotes=&Notes History
+ResourceHistory_toggleCommentWrap=&Wrap Comments
+ResourceHistory_toggleCommentFill=Fill &Paragraphs
+ResourceHistory_toggleRevDetail=&Revision Details
+ResourceHistory_toggleRevComment=Revision C&omment
+
+HardResetToRevisionAction_hardReset=Hard Reset
+HistoryPage_authorColumn=Author
+HistoryPage_authorDateColumn=Authored Date
+HistoryPage_refreshJob=Reading history from Git repository ''{0}''
+
+HistoryPage_findbar_find=Find:
+HistoryPage_findbar_next=Next
+HistoryPage_findbar_previous=Previous
+HistoryPage_findbar_ignorecase=Ignore Case
+HistoryPage_findbar_commit=Id
+HistoryPage_findbar_comments=Comments
+HistoryPage_findbar_author=Author
+HistoryPage_findbar_committer=Committer
+HistoryPage_findbar_changeto_commit=Change to Id
+HistoryPage_findbar_changeto_comments=Change to Comments
+HistoryPage_findbar_changeto_author=Change to Author
+HistoryPage_findbar_changeto_committer=Change to Committer
+HistoryPage_findbar_exceeded=Results limit exceeded
+HistoryPage_findbar_notFound=String not found
+HistoryPreferencePage_toggleAllBranches=All &Branches and Tags
+HistoryPreferencePage_toggleAdditionalRefs=&Additional Refs
+HistoryPreferencePage_toggleEmailAddresses=&E-mail addresses in Author/Committer columns
+HistoryPreferencePage_MaxBranchLength=Maximum characters to show for a &branch:
+HistoryPreferencePage_MaxTagLength=&Maximum characters to show for a tag:
+HistoryPreferencePage_ShowGroupLabel=Show
+HistoryPreferencePage_ShowInRevCommentGroupLabel=Show in Revision Comment
+
+PullOperationUI_ConnectionProblem=Git connection problem.\
+\n\nMaybe you are offline or behind a proxy.\nCheck your network connection and proxy configuration.
+PullOperationUI_NotTriedMessage=Not tried
+PullOperationUI_PullCanceledWindowTitle=Pull Canceled
+PullOperationUI_PullErrorWindowTitle=Pull Error
+PullOperationUI_PullFailed=Pull Failed
+PullOperationUI_PullingMultipleTaskName=Pulling from Multiple Repositories
+PullOperationUI_PullingTaskName=Pulling Branch {0} - {1}
+PullOperationUI_PullOperationCanceledMessage=The pull operation was canceled
+PullResultDialog_NothingToFetchFromLocal=Nothing to fetch (the fetch source is the local Repository)
+PullResultDialog_DialogTitle=Pull Result for {0}
+PullResultDialog_FetchResultGroupHeader=Fetch Result
+PullResultDialog_MergeAlreadyUpToDateMessage=Nothing to update - everything up to date
+PullResultDialog_MergeResultGroupHeader=Update Result
+PullResultDialog_RebaseStatusLabel=Rebase status
+PullResultDialog_RebaseStoppedMessage=Rebase has stopped because of conflicts
+PushAction_wrongURIDescription=Remote repositories URIs configuration is corrupted.
+PushAction_wrongURITitle=Corrupted Configuration
+PushCommand_pushBranchTitle=Push Branch
+PushCommand_pushTagTitle=Push Tag
+PushCommitHandler_pushCommitTitle=Push Commit
+PushOperationUI_MultiRepositoriesDestinationString={0} repositories
+PushOperationUI_PushJobName=Push to {0}
+
+PushWizard_cantConnectToAny=Can''t connect to any repository: {0}
+PushWizard_cantPrepareUpdatesMessage=Can't resolve ref specifications locally (local refs changed?) or create tracking ref update.
+PushWizard_cantPrepareUpdatesTitle=Preparing Ref Updates Error
+PushWizard_cantSaveMessage=Couldn't save specified specifications in configuration file.
+PushWizard_cantSaveTitle=Configuration Storage Warning
+PushWizard_jobName=Pushing to {0}
+PushWizard_missingRefsMessage=Ref specifications don't match any source ref (local refs changed?).
+PushWizard_missingRefsTitle=Missing Refs Error
+PushWizard_unexpectedError=Unexpected error occurred.
+PushWizard_windowTitleDefault=Push to Another Repository
+PushWizard_windowTitleWithDestination=Push to: {0}
+
+CommitAction_amendCommit=No changed items were selected. Do you wish to amend the last commit?
+CommitAction_amendNotPossible=Commit/amend not possible. Possible causes\:\n\n- No changed items were selected\n- Multiple repositories selected\n- No repositories selected\n- No previous commits
+CommitAction_cannotCommit=Cannot commit now
+CommitAction_CommittingChanges=Committing changes
+CommitAction_CommittingFailed=Committing failed
+CommitAction_errorComputingDiffs=Error occurred computing diffs
+CommitAction_errorRetrievingCommit=Error occurred retrieving last commit
+CommitAction_noFilesToCommit=No files to commit
+CommitAction_repositoryState=Repository state: {0}
+CommitDialog_AddFileOnDiskToIndex=Add File on &Disk to Index
+CommitDialog_AddSOB=Add Signed-off-&by
+CommitDialog_AmendPreviousCommit=Am&end Previous Commit
+CommitDialog_Author=&Author:
+CommitDialog_Commit=&Commit
+CommitDialog_CommitAndPush=Commit and &Push
+CommitDialog_CommitChanges=Commit Changes
+CommitDialog_Committer=Committer:
+CommitDialog_CommitMessage=Commit message
+CommitDialog_DeselectAll=&Deselect All
+CommitDialog_ErrorAddingFiles=Error when adding files
+CommitDialog_ErrorInvalidAuthor=Invalid author
+CommitDialog_ErrorInvalidAuthorSpecified=Invalid author specified. Please use the form\:\nA U Thor <author@example.com>
+CommitDialog_ErrorInvalidCommitterSpecified=Invalid committer specified. Please use the form\:\nC O Mitter <committer@example.com>
+CommitDialog_ErrorMustEnterCommitMessage=You must enter a commit message
+CommitDialog_ErrorNoItemsSelected=No items selected
+CommitDialog_ErrorNoItemsSelectedToBeCommitted=No items are currently selected to be committed.
+CommitDialog_ErrorNoMessage=No message
+CommitDialog_SelectAll=&Select All
+CommitDialog_ShowUntrackedFiles=Show &Untracked Files
+CommitDialog_Status=Status
+CommitDialog_StatusAdded=Added
+CommitDialog_StatusAddedIndexDiff=Added, index diff
+CommitDialog_StatusAssumeUnchaged=Assume unchanged
+CommitDialog_StatusModified=Modified
+CommitDialog_StatusModifiedIndexDiff=Mod., index diff
+CommitDialog_StatusModifiedNotStaged=Mod., not staged
+CommitDialog_StatusRemoved=Removed
+CommitDialog_StatusRemovedNotStaged=Rem., not staged
+CommitDialog_StatusUnknown=Unknown
+CommitDialog_StatusUntracked=Untracked
+CommitDialog_StatusRemovedUntracked=Removed, Untracked
+CommitDialog_AddChangeIdLabel=Compute Change-Id for Gerrit Code Review
+CommitDialog_ConfigureLink=Preferences...
+CommitDialog_ContentAssist=Content assist available for previous commit messages and the files shown
+CommitDialog_Files=Files ({0}/{1})
+CommitDialog_Message=Enter commit message.
+CommitDialog_MessageNoFilesSelected=Select one or more files to commit
+CommitDialog_Path=Path
+CommitDialog_Title=Commit Changes to Git Repository
+CommitDialog_WrongTypeOfCommitMessageProvider=The extension used as CommitMessageProvider has the wrong type (it must implement org.eclipse.egit.ui.ICommitMessageProvider)
+
+SpellcheckableMessageArea_redo=Redo
+SpellcheckableMessageArea_showWhitespace=Show &Whitespace Characters
+SpellcheckableMessageArea_undo=Undo
+SpellCheckingMessageArea_copy=&Copy
+SpellCheckingMessageArea_cut=C&ut
+SpellCheckingMessageArea_paste=&Paste
+SpellCheckingMessageArea_selectAll=Select &All
+CommitMessageComponent_MessageInvalidAuthor=Invalid author specified. Example: A U Thor <author@example.com>
+CommitMessageComponent_MessageInvalidCommitter=Invalid committer specified. Example: C O Mitter <committer@example.com>
+CommitMessageComponent_AmendingCommitInRemoteBranch=The commit being amended has already been published to a remote branch.
+CommitMessageViewer_author=Author
+CommitMessageViewer_child=Child
+CommitMessageViewer_branches=Branches
+CommitMessageViewer_MoreBranches=\ and {0} more branches
+CommitMessageViewer_BuildDiffListTaskName=Building diffs for the selected files
+CommitMessageViewer_BuildDiffTaskName=Building diff for file {0}
+CommitMessageViewer_CanNotRenderDiffMessage=Can not render diff, as the current commit has multiple parents
+CommitMessageViewer_tags=Tags
+CommitMessageViewer_follows=Follows
+CommitMessageViewer_precedes=Precedes
+CommitMessageViewer_commit=commit
+CommitMessageViewer_committer=Committer
+CommitMessageViewer_FormattingMessageTaskName=Formatting commit message
+CommitMessageViewer_GettingNextTagTaskName=Getting next tag
+CommitMessageViewer_GettingPreviousTagTaskName=Getting previous tag
+CommitMessageViewer_parent=Parent
+CompareWithHeadActionHandler_NoHeadTitle=Compare With HEAD
+CompareWithHeadActionHandler_NoHeadMessage=Comparing is not possible, as there is not yet a HEAD commit.
+CompareWithIndexAction_errorOnAddToIndex=Error during adding to index
+CompareWithPreviousActionHandler_MessageRevisionNotFound=No previous revision of {0} could be found in the repository.
+CompareWithPreviousActionHandler_TaskGeneratingInput=Generating comparison with previous revision
+CompareWithPreviousActionHandler_TitleRevisionNotFound=Previous revision not found
+CompareWithRefAction_errorOnSynchronize=Error reading from repository while preparing input for compare operation.
+
+CompareUtils_errorCommonAncestor=Error finding common ancestor for {0} and {1}
+
+ConfirmationPage_cantConnectToAnyTitle=Can't Connect
+ConfirmationPage_cantConnectToAny=Can''t connect to any URI: {0}
+ConfirmationPage_description=Confirm following expected push result.
+ConfirmationPage_errorCantResolveSpecs=Can''t resolve ref specifications locally or create tracking ref update: {0}
+ConfirmationPage_errorInterrupted=Operation was interrupted.
+ConfirmationPage_errorRefsChangedNoMatch=Local refs changed, ref specifications don't match any source ref.
+ConfirmationPage_errorUnexpected=Unexpected error occurred: {0}
+ConfirmationPage_requireUnchangedButton=Push only if remote refs don't change in the mean time
+ConfirmationPage_showOnlyIfChanged=Show final report dialog only when it differs from this confirmation report
+ConfirmationPage_title=Push Confirmation
+CreateBranchDialog_DialogTitle=Create a Local Branch
+CreateBranchDialog_OKButtonText=Create Branch...
+CreateBranchDialog_SelectRefMessage=Select a branch, tag, or reference to base the new branch on
+CreateBranchDialog_WindowTitle=Create Branch
+CreateBranchPage_BranchNameLabel=&Branch name:
+CreateBranchPage_CheckingOutMessage=Checking out new branch...
+CreateBranchPage_CheckoutButton=&Checkout new branch
+CreateBranchPage_ChooseBranchAndNameMessage=Please choose a source branch and a name for the new branch
+CreateBranchPage_ChooseNameMessage=Please choose a name for the new branch
+CreateBranchPage_CreatingBranchMessage=Creating branch...
+CreateBranchPage_LocalBranchWarningText=You are creating a branch based on a local branch
+CreateBranchPage_LocalBranchWarningTooltip=Creating a branch that is based on a local branch is only useful for specific scenarios;\n in general, you should use branches that are based on a remote tracking branch
+CreateBranchPage_MergeRadioButton=&Merge
+CreateBranchPage_MissingSourceMessage=Please select a source branch
+CreateBranchPage_NoneRadioButton=&None
+CreateBranchPage_PullMergeTooltip=Fetch (unless the base branch is a local branch), then merge the branch with the fetch result
+CreateBranchPage_PullNoneTooltip=Do not fetch and update (pull will not work for this branch)
+CreateBranchPage_PullRebaseTooltip=Fetch (unless the base branch is a local branch), then rebase the branch onto the fetch result
+CreateBranchPage_PullStrategyGroupHeader=Pull strategy
+CreateBranchPage_PullStrategyTooltip=Here you can configure how pull will work for the new branch
+CreateBranchPage_RebaseRadioButton=&Rebase
+CreateBranchPage_SourceBranchLabel=&Source ref:
+CreateBranchPage_SourceBranchTooltip=The new branch will be created from this branch
+CreateBranchPage_SourceCommitLabel=&Source ref or commit:
+CreateBranchPage_SourceCommitTooltip=The branch will be created from this commit
+CreateBranchPage_Title=Create a new branch
+CreateBranchWizard_CreationFailed=Branch could not be created
+CreateBranchWizard_NewBranchTitle=Create Branch
+CreateRepositoryPage_BareCheckbox=&Create as bare repository
+CreateRepositoryPage_BrowseButton=&Browse...
+CreateRepositoryPage_DirectoryLabel=Parent &directory:
+CreateRepositoryPage_MissingNameMessage=Please choose a name
+CreateRepositoryPage_NotADirectoryMessage=Path {0} is not a directory
+CreateRepositoryPage_NotEmptyMessage=Directory {0} is not empty
+CreateRepositoryPage_PageMessage=Please determine the directory for the new repository
+CreateRepositoryPage_PageTitle=Create a New Git Repository
+CreateRepositoryPage_PleaseSelectDirectoryMessage=Please select a directory
+CreateRepositoryPage_PleaseUseAbsoluePathMessage=Please use an absolute path
+CreateRepositoryPage_RepositoryNameLabel=&Name:
+PushResultDialog_ConfigureButton=&Configure...
+PushResultTable_columnStatusRepo=Status: Repository #{0}
+PushResultTable_columnDst=Destination Ref
+PushResultTable_columnSrc=Source Ref
+PushResultTable_columnMode=Mode
+PushResultTable_MesasgeText=Message Details
+PushResultTable_statusUnexpected=Unexpected update status: {0}
+PushResultTable_statusConnectionFailed=[connection failed]
+PushResultTable_statusDetailChanged=remote ref object changed,\nnow it''s\: {0},\nnot expected\: {1}
+PushResultTable_refNonExisting=(non existing)
+PushResultTable_repository=Repository
+PushResultTable_statusDetailDeleted=old value: {0}
+PushResultTable_statusDetailNonFastForward=non-fast-forward
+PushResultTable_statusDetailNoDelete=remote side does not support deleting refs
+PushResultTable_statusDetailNonExisting=remote ref already does not exist
+PushResultTable_statusDetailForcedUpdate=forced update (non-fast-forward)
+PushResultTable_statusDetailFastForward=fast-forward
+PushResultTable_statusRemoteRejected=[remote rejected]
+PushResultTable_statusRejected=[rejected]
+PushResultTable_statusNoMatch=[no match]
+PushResultTable_statusUpToDate=[up to date]
+PushResultTable_statusOkDeleted=[deleted]
+PushResultTable_statusOkNewBranch=[new branch]
+PushResultTable_statusOkNewTag=[new tag]
+PushToGerritPage_BranchLabel=Gerrit &Branch:
+PushToGerritPage_ContentProposalHoverText=Press {0} to see a filtered list of branch names
+PushToGerritPage_Message=Select a Gerrit URI and branch name
+PushToGerritPage_MissingBranchMessage=Select a branch
+PushToGerritPage_MissingUriMessage=Select a URI
+PushToGerritPage_Title=Push the current HEAD from repository {0} to Gerrit
+PushToGerritPage_UriLabel=&URI:
+PushToGerritWizard_Title=Push the current HEAD to Gerrit
+ResultDialog_title=Push Results: {0}
+ResultDialog_label=Pushed to {0}
+
+FetchAction_wrongURITitle=Corrupted Configuration
+FetchAction_wrongURIMessage=Remote repositories URIs configuration is corrupted.
+FetchOperationUI_FetchJobName=Fetch from {0}
+
+FetchDestinationPage_PageTitle=Please select a fetch destination
+FetchDestinationPage_CouldNotGetBranchesMessage=Could not obtain tracking branches
+FetchDestinationPage_DestinationLabel=Destination:
+FetchDestinationPage_ForceCheckbox=Update the local repository even if data could be lost
+FetchDestinationPage_PageMessage=The destination is a remote tracking branch in the local repository
+FetchDestinationPage_RepositoryLabel=Local repository:
+FetchDestinationPage_SourceLabel=Source:
+FetchDestinationPage_TrackingBranchNotFoundMessage=Remote tracking branch ''{0}'' not found in local repository
+FetchGerritChangePage_ActivateAdditionalRefsButton=Make FETCH_HEAD visible in &History View
+FetchGerritChangePage_ActivateAdditionalRefsTooltip=The History View is currently configured not to show FETCH_HEAD; if you check this, the History View settings will be changed so that FETCH_HEAD becomes visible
+FetchGerritChangePage_AfterFetchGroup=Action to perform after fetch
+FetchGerritChangePage_BranchNameText=Branch &name
+FetchGerritChangePage_ChangeLabel=&Change:
+FetchGerritChangePage_CheckingOutTaskName=Checking out change
+FetchGerritChangePage_CheckoutRadio=Check&out FETCH_HEAD
+FetchGerritChangePage_ContentAssistDescription=Patch set {0} of change {1}
+FetchGerritChangePage_ContentAssistTooltip=Press {0} to see a filtered list of changes
+FetchGerritChangePage_CreatingBranchTaskName=Creating branch
+FetchGerritChangePage_CreatingTagTaskName=Creating tag
+FetchGerritChangePage_ExistingRefMessage=A branch or tag with name {0} already exists
+FetchGerritChangePage_FetchingTaskName=Fetching change {0}
+FetchGerritChangePage_GeneratedTagMessage=Generated for Gerrit change {0}
+FetchGerritChangePage_GetChangeTaskName=Get change from Gerrit
+FetchGerritChangePage_LocalBranchRadio=Create and checkout a local &branch
+FetchGerritChangePage_MissingChangeMessage=Please provide a change
+FetchGerritChangePage_PageMessage=Please select a Gerrit URI and change to fetch
+FetchGerritChangePage_PageTitle=Fetch a change from Gerrit into repository {0}
+FetchGerritChangePage_ProvideRefNameMessage=Please provide a name for the new branch or tag
+FetchGerritChangePage_SuggestedRefNamePattern=change/{0}/{1}
+FetchGerritChangePage_TagNameText=Tag &name
+FetchGerritChangePage_TagRadio=Create and checkout a &tag
+FetchGerritChangePage_UpdateRadio=U&pdate FETCH_HEAD only
+FetchGerritChangePage_UriLabel=&URI:
+FetchGerritChangeWizard_WizardTitle=Fetch a change from Gerrit
+FetchResultDialog_ConfigureButton=&Configure...
+FetchResultDialog_labelEmptyResult=No ref to fetch from {0} - everything up to date.
+FetchResultDialog_labelNonEmptyResult=Fetched from {0}.
+FetchResultDialog_title=Fetch Results: {0}
+
+FetchResultTable_counterCommits=\ ({0})
+FetchResultTable_statusDetailCouldntLock=couldn't lock local tracking ref for update
+FetchResultTable_statusDetailFastForward=fast-forward
+FetchResultTable_statusDetailIOError=I/O error occurred during local tracking ref update
+FetchResultTable_statusDetailNonFastForward=non-fast-forward
+FetchResultTable_statusIOError=[i/o error]
+FetchResultTable_statusLockFailure=[lock fail]
+FetchResultTable_statusNew=[new]
+FetchResultTable_statusNewBranch=[new branch]
+FetchResultTable_statusNewTag=[new tag]
+FetchResultTable_statusRejected=[rejected]
+FetchResultTable_statusUnexpected=Unexpected update status: {0}
+FetchResultTable_statusUpToDate=[up to date]
+FetchSourcePage_GettingRemoteRefsTaskname=Getting remote refs
+FetchSourcePage_PageMessage=The source is a branch or tag in the remote repository
+FetchSourcePage_PageTitle=Please select a fetch source
+FetchSourcePage_RefNotFoundMessage=Ref ''{0}'' not found in remote repository
+FetchSourcePage_RepositoryLabel=Remote repository:
+FetchSourcePage_SourceLabel=Source:
+FetchWizard_cantSaveMessage=Couldn't save specified specifications in configuration file.
+FetchWizard_cantSaveTitle=Configuration Storage Warning
+FetchWizard_windowTitleDefault=Fetch from Another Repository
+FetchWizard_windowTitleWithSource=Fetch from: {0}
+FileDiffContentProvider_errorGettingDifference=Can''t get file difference of {0}.
+FileRevisionEditorInput_NameAndRevisionTitle={0} {1}
+FileTreeContentProvider_NonWorkspaceResourcesNode=Non-workspace files
+FindToolbar_NextTooltip=Go to next commit matching the search criteria
+FindToolbar_PreviousTooltip=Go to previous commit matching the search criteria
+FormatJob_buildingCommitInfo=Building Commit Info
+
+WindowCachePreferencePage_title=Git Window Cache
+WindowCachePreferencePage_packedGitWindowSize=Window size:
+WindowCachePreferencePage_packedGitLimit=Window cache limit:
+WindowCachePreferencePage_deltaBaseCacheLimit=Delta base cache limit:
+WindowCachePreferencePage_packedGitMMAP=Use virtual memory mapping
+WindowCachePreferencePage_streamFileThreshold=Stream File Threshold:
+
+ProjectsPreferencePage_AutoShareProjects=Auto share projects located in a git repository
+ProjectsPreferencePage_RestoreBranchProjects=Track each branch's imported projects and restore on checkout
+ProjectsPreferencePage_AutoIgnoreDerivedResources=Automatically ignore derived resources by adding them to .gitignore
+
+RefreshPreferencesPage_RefreshOnlyWhenActive=Refresh only when workbench is &active
+RefreshPreferencesPage_RefreshWhenIndexChange=Refresh resources when &index changes
+RefUpdateElement_CommitCountDecoration=({0})
+RefUpdateElement_CommitRangeDecoration=[{0}{1}{2}]
+RefUpdateElement_statusRejectedNonFastForward=[rejected - non-fast-forward]
+RefUpdateElement_UrisDecoration=({0})
+
+CommitDialogPreferencePage_commitMessageHistory=Maximum number of commit messages in history:
+CommitDialogPreferencePage_title=Commit Dialog
+CommitDialogPreferencePage_formatting=Formatting
+CommitDialogPreferencePage_hardWrapMessage=Hard-wrap commit message
+CommitDialogPreferencePage_hardWrapMessageTooltip=Wrap text in commit message editor while typing
+CommitDialogPreferencePage_footers=Footers
+CommitDialogPreferencePage_includeUntrackedFiles=Include selected untracked files
+CommitDialogPreferencePage_includeUntrackedFilesTooltip=Check selected untracked files by default
+CommitDialogPreferencePage_signedOffBy=Insert Signed-off-by
+CommitDialogPreferencePage_signedOffByTooltip=Insert "Signed-off-by:" footer by default
+
+BasicConfigurationDialog_DialogMessage=Git needs your name and e-mail to correctly attribute your commits. Git uses name and e-mail to identify author and committer of a commit.
+BasicConfigurationDialog_DialogTitle=Please identify yourself
+BasicConfigurationDialog_UserEmailLabel=User &e-mail
+BasicConfigurationDialog_UserNameLabel=User &name
+BasicConfigurationDialog_WindowTitle=Identify Yourself
+BranchAction_branchFailed=Branch failed
+BranchAction_cannotCheckout=Cannot checkout now
+BranchAction_checkingOut=Checking out {0} - {1}
+BranchAction_repositoryState=Repository state: {0}
+BranchConfigurationDialog_BranchConfigurationTitle=Git Branch Configuration
+BranchConfigurationDialog_EditBranchConfigMessage=Edit the upstram configuration for branch {0}
+BranchConfigurationDialog_ExceptionGettingRefs=Exception getting Refs
+BranchConfigurationDialog_RebaseLabel=&Rebase
+BranchConfigurationDialog_RemoteLabel=Rem&ote:
+BranchConfigurationDialog_SaveBranchConfigFailed=Could not save branch configuration
+BranchConfigurationDialog_UpstreamBranchLabel=Upstream &Branch:
+BranchOperationUI_DetachedHeadTitle=Detached HEAD
+BranchOperationUI_DetachedHeadMessage=You are in the 'detached HEAD' state. This means that you don't have a local branch checked out.\n\nYou can look around, but it's not recommended to commit changes. The reason is that these commits would not be on any branch and would not be visible after checking out another branch.\n\nIf you want to make changes, create or checkout a local branch first.
+BranchRenameDialog_Message=Please enter a new name for branch {0}
+BranchRenameDialog_NewNameLabel=New Branch &name:
+BranchRenameDialog_RenameExceptionMessage=Could not rename branch
+BranchRenameDialog_Title=Rename Branch
+BranchRenameDialog_WindowTitle=Rename Branch
+BranchRenameDialog_WrongPrefixErrorMessage=Can not rename Ref with name {0}
+BranchPropertySource_RebaseDescriptor=Rebase
+BranchPropertySource_RemoteDescriptor=Remote
+BranchPropertySource_UpstreamBranchDescriptor=Upstream Branch
+BranchPropertySource_UpstreamConfigurationCategory=Upstream Configuration
+BranchPropertySource_ValueNotSet=<Not set>
+BranchResultDialog_buttonCommit=Commit...
+BranchResultDialog_buttonReset=Reset
+BranchResultDialog_buttonStash=Stash...
+BranchResultDialog_CheckoutConflictsMessage=The files shown below have uncommitted changes which would be lost by checking out ''{0}''.\n\nEither commit the changes, stash the changes, or discard the changes by resetting the current branch.
+BranchResultDialog_CheckoutConflictsTitle=Checkout Conflicts
+BranchResultDialog_dontShowAgain=Don't show this confirmation dialog again
+CheckoutDialog_ErrorCouldNotCreateNewRef=Could not create new ref {0}
+CheckoutDialog_ErrorCouldNotDeleteRef=Could not delete ref {0}
+CheckoutDialog_ErrorCouldNotRenameRef=Failed to rename branch {0} -> {1}, status={2}
+
+CheckoutDialog_NewBranch=&New Branch...
+CheckoutDialog_QuestionNewBranchNameMessage=Enter new name of the {0} branch. {1} will be prepended to the name you type
+CheckoutDialog_QuestionNewBranchTitle=New branch
+CheckoutDialog_Rename=&Rename...
+CheckoutDialog_Delete=&Delete
+MergeAction_CannotMerge=Cannot merge now
+MergeAction_HeadIsNoBranch=HEAD is not pointing to a branch
+MergeAction_JobNameMerge=Merging with {0}
+MergeAction_MergeCanceledMessage=The merge operation was canceled
+MergeAction_MergeCanceledTitle=Merge Canceled
+MergeAction_MergeResultTitle=Merge Result
+MergeAction_WrongRepositoryState=The current repository state ''{0}'' does not allow merging
+MergeModeDialog_DialogTitle=Select a Merge Mode
+MergeModeDialog_DontAskAgainLabel=&Don't ask again
+MergeModeDialog_MergeMode_1_Label=Use the &workspace version of conflicting files (pre-merged by Git)
+MergeModeDialog_MergeMode_2_Label=Use &HEAD (the last local version) of conflicting files
+MergeResultDialog_couldNotFindCommit=Could not find commit: {0}
+MergeResultDialog_description=Description
+MergeResultDialog_id=Commit Id
+MergeResultDialog_failed=Failed Paths
+MergeResultDialog_mergeInput=Merge input
+MergeResultDialog_mergeResult=Merge result
+MergeResultDialog_newHead=New HEAD
+MergeResultDialog_nMore=... {0} more
+MergeResultDialog_result=Result
+MergeTargetSelectionDialog_ButtonMerge=&Merge
+MergeTargetSelectionDialog_SelectRef=Select a branch or tag to merge into the currently checked out branch
+MergeTargetSelectionDialog_SelectRefWithBranch=Select a branch or tag to merge into the ''{0}'' branch
+MergeTargetSelectionDialog_TitleMerge=Merge Branch
+MergeTargetSelectionDialog_TitleMergeWithBranch=Merge ''{0}''
+MergeTargetSelectionDialog_FastForwardGroup=Fast forward options
+MergeTargetSelectionDialog_FastForwardButton=If a fast-forward, &only update the branch pointer
+MergeTargetSelectionDialog_NoFastForwardButton=If a fast-forward, create a &merge commit
+MergeTargetSelectionDialog_OnlyFastForwardButton=If &not a fast-forward, fail
+MergeTargetSelectionDialog_MergeTypeGroup=Merge options
+MergeTargetSelectionDialog_MergeTypeCommitButton=&Commit (commit the result)
+MergeTargetSelectionDialog_MergeTypeSquashButton=&Squash (do not make a commit)
+
+DecoratorPreferencesPage_addVariablesTitle=Add Variables
+DecoratorPreferencesPage_addVariablesAction=Add &Variables...
+DecoratorPreferencesPage_addVariablesAction2=Add Va&riables...
+DecoratorPreferencesPage_addVariablesAction3=Add Var&iables...
+DecoratorPreferencesPage_recomputeAncestorDecorations=Re-decorate &ancestors when decorating changed resources
+DecoratorPreferencesPage_recomputeAncestorDecorationsTooltip=Enabling this option will cause the ancestor-tree of any updated resources to also be re-decorated (minor performance impact).
+DecoratorPreferencesPage_description=Shows Git specific information on resources in projects under version control.
+DecoratorPreferencesPage_preview=Preview:
+DecoratorPreferencesPage_fileFormatLabel=&Files:
+DecoratorPreferencesPage_folderFormatLabel=F&olders:
+DecoratorPreferencesPage_projectFormatLabel=&Projects:
+DecoratorPreferencesPage_labelDecorationsLink=See <a>''{0}''</a> to enable or disable Git decorations.
+DecoratorPreferencesPage_colorsAndFontsLink=See <a>''{0}''</a> to configure the font and color decorations.
+DecoratorPreferencesPage_generalTabFolder=&General
+DecoratorPreferencesPage_bindingResourceName=Name of the resource being decorated
+DecoratorPreferencesPage_bindingBranchName=Current branch of the repository
+DecoratorPreferencesPage_bindingBranchStatus=Branch status (compared to remote-tracking)
+DecoratorPreferencesPage_bindingDirtyFlag=Flag indicating whether or not the resource is dirty
+DecoratorPreferencesPage_bindingStagedFlag=Flag indicating whether or not the resource is staged
+DecoratorPreferencesPage_selectVariablesToAdd=Select the &variables to add to the decoration format:
+DecoratorPreferencesPage_textLabel=T&ext Decorations
+DecoratorPreferencesPage_iconLabel=&Icon Decorations
+DecoratorPreferencesPage_iconsShowTracked=Tracked resources
+DecoratorPreferencesPage_iconsShowUntracked=Untracked resources
+DecoratorPreferencesPage_iconsShowStaged=Staged resources
+DecoratorPreferencesPage_iconsShowConflicts=Conflicting resources
+DecoratorPreferencesPage_iconsShowAssumeValid=Assumed unchanged resources
+DecoratorPreferencesPage_changeSetLabelFormat=Commits:
+DecoratorPreferencesPage_otherDecorations=Other
+DecoratorPreferencesPage_dateFormat=Date format:
+DecoratorPreferencesPage_dateFormatPreview=Date preview:
+DecoratorPreferencesPage_wrongDateFormat=#Incorrect date format#
+DecoratorPreferencesPage_bindingChangeSetAuthor=Commit author name;
+DecoratorPreferencesPage_bindingChangeSetCommitter=Commit committer name;
+DecoratorPreferencesPage_bindingChangeSetDate=Commit creation date (see date format setting);
+DecoratorPreferencesPage_bindingChangeSetShortMessage=First line of commit message text;
+
+Decorator_exceptionMessage=Errors occurred while applying Git decorations to resources.
+DeleteBranchCommand_CannotDeleteCheckedOutBranch=Can not delete the currently checked out branch
+DeleteBranchCommand_DeletingBranchesProgress=Deleting branches
+DeleteBranchDialog_DialogMessage=Select a branch to delete
+DeleteBranchDialog_DialogTitle=Delete a branch
+DeleteBranchDialog_WindowTitle=Delete branch
+DeleteBranchOnCommitHandler_SelectBranchDialogMessage=Please select the branches you want to delete
+DeleteBranchOnCommitHandler_SelectBranchDialogTitle=Delete Branches
+DeleteRepositoryConfirmDialog_DeleteRepositoryMessage=This will permanently delete repository ''{0}''.
+DeleteRepositoryConfirmDialog_DeleteRepositoryTitle=Delete Repository {0}
+DeleteRepositoryConfirmDialog_DeleteRepositoryWindowTitle=Delete Repository
+DeleteRepositoryConfirmDialog_DeleteWorkingDirectoryCheckbox=Also delete repository content in &working directory {0}
+DeleteRepositoryConfirmDialog_DeleteProjectsCheckbox=Remove the {0} projects that belong to the removed repositories from the workspace
+DeleteTagCommand_messageConfirmMultipleTag=Are you sure you want to delete these {0} tags?
+DeleteTagCommand_messageConfirmSingleTag=Are you sure you want to delete tag ''{0}''?
+DeleteTagCommand_taskName=Deleting tag
+DeleteTagCommand_titleConfirm=Confirm Tag Deletion
+DeleteResourcesOperationUI_confirmActionTitle=Delete Resources
+DeleteResourcesOperationUI_confirmActionMessage=Are you sure you want to delete the selected files from the file system?
+DeleteResourcesOperationUI_deleteFailed=Deleting resources failed
+
+IgnoreActionHandler_addToGitignore=Add to .gitignore
+
+RepositoriesView_BranchDeletionFailureMessage=Branch deletion failed
+RepositoriesView_Branches_Nodetext=Branches
+RepositoriesView_ClipboardContentNoGitRepoMessage=Path {0} does not appear to be a Git repository location
+RepositoriesView_ClipboardContentNotDirectoryOrURIMessage=Clipboard content is neither a directory path nor a valid git URI
+RepositoriesView_ConfirmDeleteRemoteHeader=Confirm Remote Configuration Deletion
+RepositoriesView_ConfirmDeleteRemoteMessage=Are you sure you want to remove remote configuration ''{0}''?
+RepositoriesView_ConfirmProjectDeletion_Question=There are {0} projects that belong to the removed repositories, do you want to remove them from the workspace?
+RepositoriesView_ConfirmProjectDeletion_WindowTitle=Confirm Project Deletion
+RepositoriesView_DeleteRepoDeterminProjectsMessage=Determining projects that must be deleted
+RepositoriesView_Error_WindowTitle=Error
+RepositoriesView_ErrorHeader=Error
+RepositoriesView_ExceptionLookingUpRepoMessage=An exception occurred while looking up the repository path ''{0}''; it will be removed from the Git Repositories view
+RepositoriesView_linkAdd=Add an existing local Git repository
+RepositoriesView_linkClone=Clone a Git repository
+RepositoriesView_linkCreate=Create a new local Git repository
+RepositoriesView_messsageEmpty=Select one of the following to add a repository to this view:
+RepositoriesView_NothingToPasteMessage=Clipboard contains no data to paste
+RepositoriesView_PasteRepoAlreadyThere=Repository at location {0} is already in the list
+RepositoriesView_RemotesNodeText=Remotes
+RepositoriesView_WorkingDir_treenode=Working Directory
+RepositoriesViewContentProvider_ExceptionNodeText=Exception encountered while fetching children
+RepositoriesViewLabelProvider_LocalNodetext=Local
+RepositoriesViewLabelProvider_RemoteTrackingNodetext=Remote Tracking
+RepositoriesViewLabelProvider_StashNodeText=Stashed Commits
+RepositoriesViewLabelProvider_SubmodulesNodeText=Submodules
+RepositoriesViewLabelProvider_SymbolicRefNodeText=References
+RepositoriesViewLabelProvider_TagsNodeText=Tags
+
+DialogsPreferencePage_DetachedHeadCombo=D&etached HEAD warning
+DialogsPreferencePage_DontShowDialog=Do not prompt
+DialogsPreferencePage_HideConfirmationGroupHeader=Show confirmation dialogs
+DialogsPreferencePage_HideWarningGroupHeader=Log warnings
+DialogsPreferencePage_HomeDirWarning=&Home directory warning (Windows only)
+DialogsPreferencePage_GitPrefixWarning=&Git prefix warning (Windows typically)
+DialogsPreferencePage_RebaseCheckbox=&Rebase confirmation
+DialogsPreferencePage_ShowDialog=Prompt
+DialogsPreferencePage_ShowInitialConfigCheckbox=&Initial configuration
+DialogsPreferencePage_ShowCloneFailedDialog=Clone failed error
+DiffEditorPage_TaskGeneratingDiff=Generating diff
+DiffEditorPage_TaskUpdatingViewer=Updating diff viewer
+DiffEditorPage_Title=Diff
+DiscardChangesAction_confirmActionTitle=Discard Local Changes
+DiscardChangesAction_confirmActionMessage=This will discard all local changes for the selected resources. Untracked files will be ignored. Are you sure you want to do this?
+DiscardChangesAction_discardChanges=Discard Changes
+Disconnect_disconnect=Disconnect
+
+GitCompareEditorInput_CompareResourcesTaskName=Comparing Resources
+GitCompareEditorInput_EditorTitle=Repository ''{0}'': Comparing ''{1}'' with ''{2}''
+GitCompareEditorInput_EditorTitleMultipleResources=Multiple Resources: Comparing  ''{0}'' with ''{1}''
+GitCompareEditorInput_EditorTitleSingleResource=''{0}'': Comparing ''{1}'' with ''{2}''
+GitCompareEditorInput_ResourcesInDifferentReposMessagge=Resources belong to different repositories
+GitCompareFileRevisionEditorInput_CompareInputTitle={0}
+GitCompareFileRevisionEditorInput_CompareTooltip=Compare {0} {1} and {2}
+GitCompareFileRevisionEditorInput_CurrentRevision=Current Revision
+GitCompareFileRevisionEditorInput_CurrentTitle=Current
+GitCompareFileRevisionEditorInput_contentIdentifier=Problem getting content identifier
+GitCompareFileRevisionEditorInput_LocalHistoryLabel=Local history: {0} {1}
+GitCompareFileRevisionEditorInput_LocalLabel=Local: {0}
+GitCompareFileRevisionEditorInput_LocalRevision=Local Revision
+GitCompareFileRevisionEditorInput_RevisionLabel={0} {1} ({2})
+GitCompareFileRevisionEditorInput_LocalVersion={0} (local version)
+GitCompareFileRevisionEditorInput_StagedVersion={0} (staged version)
+GitCreateGeneralProjectPage_DirLabel=Directory
+GitCreateGeneralProjectPage_DirNotExistMessage=Directory {0} does not exist
+GitCreateGeneralProjectPage_EnterProjectNameMessage=Please provide a project name
+GitCreateGeneralProjectPage_FileExistsInDirMessage=A {0} file already exists in directory {1}
+GitCreateGeneralProjectPage_FileNotDirMessage=File {0} is not a directory
+GitCreateGeneralProjectPage_PorjectAlreadyExistsMessage=Project {0} already exists
+GitCreateGeneralProjectPage_ProjectNameLabel=Project name
+GitCreatePatchAction_cannotCreatePatch=Cannot create patch
+GitCreatePatchAction_workingTreeClean=There are no changes in the workspace for the current selection
+GitCreatePatchWizard_Browse=B&rowse...
+GitCreatePatchWizard_Clipboard=&Clipboard
+GitCreatePatchWizard_ContextMustBePositiveInt=Context must be a valid number of lines ( >= 0 )
+GitCreatePatchWizard_CreatePatchTitle=Create Patch
+GitCreatePatchWizard_File=Fil&e
+GitCreatePatchWizard_Format=Format
+GitCreatePatchWizard_InternalError=An internal error occurred.
+GitCreatePatchWizard_SelectLocationDescription=Select the location for the patch.
+GitCreatePatchWizard_SelectLocationTitle=Create a Patch
+GitCreatePatchWizard_SelectOptionsDescription=Select options for patch creation
+GitCreatePatchWizard_SelectOptionsTitle=Select Options
+GitCreatePatchWizard_FilesystemError=Please select a location in the file system by browsing.
+GitCreatePatchWizard_FilesystemInvalidError=Please enter a valid location.
+GitCreatePatchWizard_FilesystemDirectoryError=Please enter a file name.
+GitCreatePatchWizard_FilesystemDirectoryNotExistsError=The specified directory does not exist.
+GitCreatePatchWizard_LinesOfContext=Lines of &context:
+GitCreatePatchWizard_ReadOnlyTitle=Read-only file
+GitCreatePatchWizard_ReadOnlyMsg=The specified file is read-only and cannot be overwritten.
+GitCreatePatchWizard_OverwriteTitle=Confirm Overwrite
+GitCreatePatchWizard_OverwriteMsg=A file with that name already exists. Overwrite?
+GitCreatePatchWizard_Workspace=&Workspace
+GitCreatePatchWizard_WorkspacePatchDialogTitle=Set a Patch Location
+GitCreatePatchWizard_WorkspacePatchDialogDescription=Select a folder in the workspace and enter a name for the patch.
+GitCreatePatchWizard_WorkspacePatchDialogEnterFileName=Please enter a file name.
+GitCreatePatchWizard_WorkspacePatchDialogEnterValidLocation=Please enter a valid location.
+GitCreatePatchWizard_WorkspacePatchDialogFileName=Fi&le name:
+GitCreatePatchWizard_WorkspacePatchDialogSavePatch=Save Patch
+GitCreatePatchWizard_WorkspacePatchEnterValidFileName=Please enter a valid filename.
+GitCreatePatchWizard_WorkspacePatchFolderExists=The specified path points to an existing folder.
+GitCreatePatchWizard_WorkspacePatchProjectClosed=The specified path points to a closed project.
+GitCreatePatchWizard_WorkspacePatchSelectByBrowsing=Please select a location in the workspace by browsing.
+GitCreateProjectViaWizardWizard_AbortedMessage=Action was aborted
+GitCreateProjectViaWizardWizard_WizardTitle=Import Projects from Git Repository {0}
+GitImportWithDirectoriesPage_PageMessage=Depending on the wizard, you may select a directory to determine the wizard's scope
+GitImportWithDirectoriesPage_PageTitle=Select a wizard to use for importing projects
+GitImportWithDirectoriesPage_SelectFolderMessage=Please select a folder
+GitImportWizard_errorParsingURI=The URI of the repository to be cloned can't be parsed
+GitImportWizard_noRepositoryInfo=The repository info could not be created
+GitImportWizard_WizardTitle=Import Projects from Git
+GitScopeOperation_couldNotDetermineState=Could not determine state of changed files
+GitScopeOperation_GitScopeManager=Git Scope Manager
+GitSelectRepositoryPage_AddButton=&Add...
+GitSelectRepositoryPage_AddTooltip=Add a Git repository from the local file system
+GitSelectRepositoryPage_CloneButton=&Clone...
+GitSelectRepositoryPage_CloneTooltip=Clone a Git repository and add it to the list
+GitSelectRepositoryPage_NoRepoFoundMessage=No repositories found, please clone or add a repository
+GitSelectRepositoryPage_PageMessage=You can also clone a repository or add local repositories to the list
+GitSelectRepositoryPage_PageTitle=Select a Git Repository
+GitSelectRepositoryPage_PleaseSelectMessage=Please select a repository from the list
+GitSelectWizardPage_ImportAsGeneralButton=Import as &general project
+GitSelectWizardPage_ImportExistingButton=Import &existing projects
+GitSelectWizardPage_ProjectCreationHeader=Wizard for project import
+GitSelectWizardPage_UseNewProjectsWizardButton=Use the New &Project wizard
+ConfigurationChecker_gitPrefixWarningMessage=\
+Warning: EGit couldn't detect the installation path "gitPrefix" of native Git. Hence EGit can't respect system level\n\
+Git settings which might be configured in ${gitPrefix}/etc/gitconfig under the native Git installation directory.\n\
+The most important of these settings is core.autocrlf. Git for Windows by default sets this parameter to true in\n\
+this system level configuration. The Git installation location can be configured on the\n\
+Team > Git > Configuration preference page's 'System Settings' tab.\n\
+This warning can be switched off on the Team > Git > Confirmations and Warnings preference page.
+ConfigurationChecker_checkConfiguration=Check Configuration
+ConfigurationChecker_homeNotSet=\
+Warning: The environment variable HOME is not set. The following directory will be used to store the Git\n\
+user global configuration and to define the default location to store repositories: ''{0}''. If this is\n\
+not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and\n\
+EGit might behave differently since they see different configuration options.\n\
+This warning can be switched off on the Team > Git > Confirmations and Warnings preference page.
+ConfigurationEditorComponent_BrowseForPrefix=&Browse...
+ConfigurationEditorComponent_CannotChangeGitPrefixError=Cannot change Git prefix
+ConfigurationEditorComponent_ConfigLocationLabel=&Location:
+ConfigurationEditorComponent_EmptyStringNotAllowed=Empty string is not allowed
+ConfigurationEditorComponent_KeyColumnHeader=Key
+ConfigurationEditorComponent_AddButton=Add &Entry...
+ConfigurationEditorComponent_NoConfigLocationKnown=Unknown
+ConfigurationEditorComponent_NoEntrySelectedMessage=No configuration entry selected
+ConfigurationEditorComponent_NoSectionSubsectionMessage=Neither a section nor subsection
+ConfigurationEditorComponent_OpenEditorButton=&Open
+ConfigurationEditorComponent_OpenEditorTooltip=Open a text editor for this configuration
+ConfigurationEditorComponent_ReadOnlyLocationFormat={0} (non-writable)
+ConfigurationEditorComponent_RemoveButton=&Remove
+ConfigurationEditorComponent_RemoveTooltip=Removes the selected entry or all entries in the selected section or subsection
+ConfigurationEditorComponent_GitPrefixSelectionErrorMessage=This directory does not look like a Git installation directory.\nYou do not need this setting unless you have a system wide configuration file.
+ConfigurationEditorComponent_GitPrefixSelectionErrorTitle=Git Prefix Selection
+ConfigurationEditorComponent_RemoveSectionMessage=All entries in section ''{0}'' will be removed.\n\nDo you want to continue?
+ConfigurationEditorComponent_RemoveSectionTitle=Remove Section
+ConfigurationEditorComponent_RemoveSubsectionMessage=All entries in subsection ''{0}'' will be removed.\n\nDo you want to continue?
+ConfigurationEditorComponent_RemoveSubsectionTitle=Remove Subsection
+ConfigurationEditorComponent_SelectGitInstallation=Select the Git Installation
+ConfigurationEditorComponent_ValueColumnHeader=Value
+ConfigurationEditorComponent_WrongNumberOfTokensMessage=Wrong number of tokens
+ConfigureGerritWizard_title=Gerrit Configuration
+ContinueRebaseCommand_CancelDialogMessage=The abort operation was canceled
+ContinueRebaseCommand_JobName=Continuing Rebase
+MixedResetToRevisionAction_mixedReset=Mixed Reset
+
+GlobalConfigurationPreferencePage_systemSettingTabTitle=&System Settings
+GlobalConfigurationPreferencePage_userSettingTabTitle=&User Settings
+GlobalConfigurationPreferencePage_repositorySettingTabTitle=Repository Sett&ings
+GlobalConfigurationPreferencePage_repositorySettingRepositoryLabel=Reposi&tory:
+GlobalConfigurationPreferencePage_repositorySettingNoRepositories=No repositories configured
+
+UIIcons_errorDeterminingIconBase=Can't determine icon base.
+UIIcons_errorLoadingPluginImage=Can't load plugin image.
+UIUtils_CollapseAll=Collapse All
+UIUtils_ExpandAll=Expand All
+UIUtils_PressShortcutMessage=Press {0} or begin typing to see a filtered list of previously used values (use "*" as wildcard)
+UIUtils_StartTypingForPreviousValuesMessage=Start typing to see a filtered list of previously used values (use "*" as wildcard)
+UIUtils_ShowInMenuLabel=Sho&w In
+UnmergedBranchDialog_Message=Not all commits of these branches have been merged into the currently checked out branch.\n\nDo you still want to delete these branches?
+UnmergedBranchDialog_Title=Confirm Branch Deletion
+Untrack_untrack=Untrack
+
+TagAction_cannotCheckout=Cannot checkout now
+TagAction_cannotGetBranchName=Cannot get actual branch name
+TagAction_repositoryState=Cannot checkout repository because it is in state: {0}
+TagAction_errorWhileGettingRevCommits=An error occurred while getting list of commits.
+TagAction_unableToResolveHeadObjectId=Unable to resolve object id associated with current HEAD.
+TagAction_creating=Creating {0} tag.
+TagAction_taggingFailed=Tagging failed
+
+CreateTagDialog_tagName=Tag &name*:
+CreateTagDialog_tagMessage=Tag &message*:
+CreateTagDialog_questionNewTagTitle=Create New Tag on Branch ''{0}''
+CreateTagDialog_overwriteTag=Force &replace existing tag
+CreateTagDialog_overwriteTagToolTip=Select this option if you want to change message or commit associated with already existing tag.
+CreateTagDialog_existingTags=&Existing tags:
+CreateTagDialog_advanced=&Advanced
+CreateTagDialog_advancedToolTip=In the advanced section you may choose the commit to be tagged.
+CreateTagDialog_advancedMessage=Choose commit that should be associated with this tag.
+CreateTagDialog_tagNameToolTip=Start typing tag name to filter list of existing tags.
+CreateTagDialog_clearButton=C&lear
+CreateTagDialog_clearButtonTooltip=Clear all dialog fields.
+CreateTagDialog_CreateTagOnCommitTitle=Create a New Tag on Commit {0}
+CreateTagDialog_ExceptionRetrievingTagsMessage=Exception while retrieving existing tags
+CreateTagDialog_GetTagJobName=Get existing tags for the Create Tag Dialog
+CreateTagDialog_LightweightTagMessage=This is a lightweight tag which can not be edited
+CreateTagDialog_LoadingMessageText=Loading...
+CreateTagDialog_Message=Create a new tag or replace an existing one
+CreateTagDialog_NewTag=Create New Tag
+
+CommitCombo_showSuggestedCommits=Start typing SHA-1 of existing commit or part of first line in commit message to see suggested commits.
+CommitCommand_committingNotPossible=Committing not possible
+CommitCommand_noProjectsImported=No projects are imported into the workspace for this repository. For the time being committing is currently only possible for workspace resources.
+
+CommitAction_commit=Commit...
+CommitAction_ErrorReadingMergeMsg=Error reading from file .git/MERGE_MSG
+CommitAction_MergeHeadErrorMessage=The file .git/MERGE_MSG was not found although being in state "merged".
+CommitAction_MergeHeadErrorTitle=Inconsistent Merge State
+CommitActionHandler_calculatingChanges=Calculating changes in selected repositories
+CommitActionHandler_errorBuildingScope=Error occurred while building scope for committing changes
+CommitActionHandler_lookingForChanges=Looking for uncommitted changes
+CommitActionHandler_repository=Repository: {0}
+CommitEditor_couldNotShowRepository=Could not show repository
+CommitEditor_showGitRepo=Show Git repository
+CommitEditor_TitleHeader=Commit {0}
+CommitEditorInput_Name={0} [{1}]
+CommitEditorInput_ToolTip=Commit {0} in repository {1}
+CommitEditorPage_JobName=Loading commit ''{0}''
+CommitEditorPage_SectionBranchesEmpty=Branches
+CommitEditorPage_LabelAuthor={0} <{1}> on {2}
+CommitEditorPage_LabelCommitter={0} <{1}> on {2}
+CommitEditorPage_LabelParent=Parent:
+CommitEditorPage_LabelTags=Tags:
+CommitEditorPage_SectionBranches=Branches ({0})
+CommitEditorPage_SectionFiles=Files ({0})
+CommitEditorPage_SectionFilesEmpty=Files
+CommitEditorPage_SectionMessage=Message
+CommitEditorPage_Title=Commit
+CommitEditorPage_TooltipAuthor=Author
+CommitEditorPage_TooltipCommitter=Committer
+CommitEditorPage_TooltipSignedOffByAuthor=Signed off by author
+CommitEditorPage_TooltipSignedOffByCommitter=Signed off by committer
+
+Header_contextMenu_copy=&Copy
+Header_contextMenu_copy_SHA1=Copy &SHA-1
+Header_copy_SHA1_error_title= Problem Copying SHA-1 to Clipboard
+Header_copy_SHA1_error_message= There was a problem when accessing the system clipboard. Retry?
+
+MergeHandler_SelectBranchMessage=There is more than one ref for this commit. Please select the ref you want to merge.
+MergeHandler_SelectBranchTitle=Select a Ref for Merge
+MultiPullResultDialog_DetailsButton=&Details
+MultiPullResultDialog_FetchStatusColumnHeader=Fetch Status
+MultiPullResultDialog_MergeResultMessage=Merge result: {0}
+MultiPullResultDialog_NothingFetchedStatus=Nothing fetched
+MultiPullResultDialog_NothingUpdatedStatus=Nothing updated
+MultiPullResultDialog_OkStatus=OK
+MultiPullResultDialog_FailedStatus=Failed
+MultiPullResultDialog_OverallStatusColumnHeader=Overall Status
+MultiPullResultDialog_RebaseResultMessage=Rebase result: {0}
+MultiPullResultDialog_RepositoryColumnHeader=Repository
+MultiPullResultDialog_UnknownStatus=Unknown
+MultiPullResultDialog_UpdatedMessage={0} refs were updated
+MultiPullResultDialog_UpdatedOneMessage=1 ref was updated
+MultiPullResultDialog_UpdateStatusColumnHeader=Update Status
+MultiPullResultDialog_WindowTitle=Pull Result for Multiple Repositories
+
+CommitFileDiffViewer_CanNotOpenCompareEditorTitle=Can not Open Compare Editor
+CommitFileDiffViewer_CompareMenuLabel=Compare with &Version in Ancestor
+CommitFileDiffViewer_CompareWorkingDirectoryMenuLabel=Compare with &Workspace
+CommitFileDiffViewer_FileDoesNotExist=File {0} does not exist in the workspace
+CommitFileDiffViewer_MergeCommitMultiAncestorMessage=This is a merge commit with more than one ancestor
+CommitFileDiffViewer_notContainedInCommit=File {0} is not contained in commit {1}
+CommitFileDiffViewer_OpenInEditorMenuLabel=Open &This Version
+CommitFileDiffViewer_OpenWorkingTreeVersionInEditorMenuLabel=&Open Workspace Version
+CommitFileDiffViewer_ShowAnnotationsMenuLabel=Show Annotations
+CommitGraphTable_CommitId=Id
+CommitGraphTable_Committer=Committer
+CommitGraphTable_committerDataColumn=Committed Date
+CommitGraphTable_CompareWithEachOtherInTreeMenuLabel=Compare with Each Other in &Tree
+CommitGraphTable_DeleteBranchAction=&Delete Branch
+CommitGraphTable_messageColumn=Message
+CommitGraphTable_OpenCommitLabel=Open in Commit &Viewer
+CommitGraphTable_RenameBranchMenuLabel=Re&name Branch...
+CommitGraphTable_UnableToCreatePatch=Unable to create patch for {0}
+CommitGraphTable_UnableToWritePatch=Unable to write temporary patch for {0}
+CommitHelper_couldNotFindMergeMsg=Inconsistent merge state: could not find file {0} in .git folder. This file contains the commit message for a merge commit.
+CommitResultLabelProvider_SectionAuthor=\ ({0} on {1})
+CommitResultLabelProvider_SectionMessage={0}: {1}
+CommitResultLabelProvider_SectionRepository=\ [{0}]
+CommitSearchPage_Author=&Author
+CommitSearchPage_CaseSensitive=&Case sensitive
+CommitSearchPage_CheckAll=Check all
+CommitSearchPage_CommitId=Comm&it id
+CommitSearchPage_Committer=C&ommitter
+CommitSearchPage_ContainingText=Containing &text:
+CommitSearchPage_ContainingTextHint=(* = any string, ? = any character, \\ = escape for literals: * ? \\)
+CommitSearchPage_Message=&Message
+CommitSearchPage_ParentIds=&Parent id(s)
+CommitSearchPage_RegularExpression=Regular e&xpression
+CommitSearchPage_Repositories=Repositories ({0}/{1})
+CommitSearchPage_Scope=Scope
+CommitSearchPage_SearchAllBranches=Search all &branches of selected repositories
+CommitSearchPage_TreeId=T&ree id
+CommitSearchPage_UncheckAll=Uncheck all
+CommitSearchQuery_Label=Git Commit Search
+CommitSearchQuery_TaskSearchCommits=Searching commits in {0}
+CommitSearchResult_LabelPlural=''{0}'' - {1} commit matches
+CommitSearchResult_LabelSingle=''{0}'' - 1 commit match
+CommitSelectDialog_AuthoColumn=Author
+CommitSelectDialog_DateColumn=Date
+CommitSelectDialog_IdColumn=Id
+CommitSelectDialog_Message=Please select a Commit
+CommitSelectDialog_MessageColumn=Message
+CommitSelectDialog_Title=Commit Selection
+CommitSelectDialog_WindowTitle=Commit Selection
+CommitSelectionDialog_BuildingCommitListMessage=Building commit list
+CommitSelectionDialog_DialogMessage=Please select a commit from the list
+CommitSelectionDialog_DialogTitle={0} commits in repository {1}
+CommitSelectionDialog_FoundCommitsMessage=Found {0} commits
+CommitSelectionDialog_IncompleteListMessage=The commit list may be incomplete
+CommitSelectionDialog_LinkSearch=<a>Search repositories for commits...</a>
+CommitSelectionDialog_Message=&Enter branch, tag, or commit SHA-1:
+CommitSelectionDialog_SectionMessage=: {0}
+CommitSelectionDialog_SectionRepo=\ [{0}]
+CommitSelectionDialog_TaskSearching=Searching commits
+CommitSelectionDialog_Title=Open Git Commit
+CommitSelectionDialog_WindowTitle=Select a Commit
+CommitUI_commitFailed=Commit failed
+CommitUI_pushFailedTitle=Push failed
+CommitUI_pushFailedMessage=Could not push {0} to {1}: {2}
+
+GitSynchronizeWizard_synchronize=Synchronize
+GitChangeSetModelProviderLabel=Git Commits
+
+GitBranchSynchronizeWizardPage_title=Synchronize Git
+GitBranchSynchronizeWizardPage_description=Select destination for repositories to be synchronized.
+GitBranchSynchronizeWizardPage_repositories=Repositories
+GitBranchSynchronizeWizardPage_destination=Destination
+GitBranchSynchronizeWizardPage_includeUncommitedChanges=Include local &uncommitted changes in comparison
+GitBranchSynchronizeWizardPage_fetchChangesFromRemote=Fetch changes from remote
+GitBranchSynchronizeWizardPage_selectAll=Select All
+GitBranchSynchronizeWizardPage_deselectAll=Deselect All
+
+GitTraceConfigurationDialog_ApplyButton=&Apply
+GitTraceConfigurationDialog_DefaultButton=&Default
+GitTraceConfigurationDialog_DialogTitle=Maintain the Git Trace Configuration
+GitTraceConfigurationDialog_LocationHeader=Location
+GitTraceConfigurationDialog_MainSwitchNodeText=Main switch for plug-in {0}
+GitTraceConfigurationDialog_OpenInEditorButton=Open in &Editor
+GitTraceConfigurationDialog_PlatformSwitchCheckbox=Enable &Platform Trace
+GitTraceConfigurationDialog_PlatformTraceDisabledMessage=Platform Trace is currently disabled, please enable it in order to edit the trace configuration
+GitTraceConfigurationDialog_ShellTitle=Git Trace Configuration
+GitTraceConfigurationDialog_TraceFileLocationLabel=Trace File &Location:
+
+ImportProjectsWrongSelection = Wrong selection
+ImportProjectsSelectionInRepositoryRequired = A folder selection in the Repository View is required
+
+LocalFileRevision_CurrentVersion=*({0})
+LocalFileRevision_currentVersionTag=<current version>
+LocalNonWorkspaceTypedElement_errorWritingContents=Error writing contents for local non-workspace element.
+LoginDialog_changeCredentials=Change stored credentials
+LoginDialog_login=Login
+LoginDialog_password=Password
+LoginDialog_repository=Repository
+LoginDialog_storeInSecureStore=Store in Secure Store
+LoginDialog_user=User
+LoginService_readingCredentialsFailed=Reading credentials failed
+LoginService_storingCredentialsFailed=Storing credentials failed
+NewRemoteDialog_ConfigurationMessage=You need to configure the new remote for either fetch or push; you can add configuration for the other direction later
+NewRemoteDialog_DialogTitle=Please enter a name for the new remote
+NewRemoteDialog_FetchRadio=Configure &fetch
+NewRemoteDialog_NameLabel=Remote &name:
+NewRemoteDialog_PushRadio=Configure &push
+NewRemoteDialog_RemoteAlreadyExistsMessage=Remote {0} already exists
+NewRemoteDialog_WindowTitle=New Remote
+NewRepositoryWizard_WizardTitle=Create a Git Repository
+NonDeletedFilesDialog_NonDeletedFilesMessage=The files below could not be deleted, \nperhaps because of some temporary file locks\nor because a directory represents a submodule
+NonDeletedFilesDialog_NonDeletedFilesTitle=Not deleted Files
+NonDeletedFilesDialog_RetryDeleteButton=&Retry delete
+NonDeletedFilesTree_FileSystemPathsButton=Show file &system paths
+NonDeletedFilesTree_RepoRelativePathsButton=Show &repository relative paths
+NonDeletedFilesTree_RepositoryLabel=Repository:
+NonDeletedFilesTree_ResourcePathsButton=Show resource &paths
+NoteDetailsPage_ContentSection=Note Content
+NotesBlock_NotesSection=Notes ({0})
+NotesEditorPage_Title=Notes
+
+RemoteConnectionPreferencePage_TimeoutLabel=&Remote connection timeout (seconds):
+RemoteConnectionPreferencePage_ZeroValueTooltip=0 is equivalent to no timeout
+RemoveCommand_ConfirmDeleteBareRepositoryMessage=This will permanently delete repository ''{0}''.\n\nDo you want to continue?
+RemoveCommand_ConfirmDeleteBareRepositoryTitle=Delete Bare Repository
+RenameBranchDialog_DialogMessage=Select a branch to rename
+RenameBranchDialog_DialogTitle=Rename a Branch
+RenameBranchDialog_NewNameInputDialogPrompt=Enter new name of the {0} branch. {1} will be prepended to the name you type
+RenameBranchDialog_RenameBranchDialogNewNameInputWindowTitle=New Branch Name
+RenameBranchDialog_RenameButtonLabel=&Rename
+RenameBranchDialog_RenameErrorMessage=Failed to rename branch {0} -> {1}, status={2}
+RenameBranchDialog_WindowTitle=Branch Rename
+RenameBranchOnCommitHandler_SelectBranchDialogMessage=Please select the branch you want to rename
+RenameBranchOnCommitHandler_SelectBranchDialogTitle=Rename Branch
+RevertFailureDialog_Message=Reverting commit ''{0}'' did not successfully complete.\n\nThe following files could not be reverted:
+RevertFailureDialog_MessageNoFiles=Reverting commit ''{0}'' did not successfully complete.
+RevertFailureDialog_ReasonChangesInIndex=Local Changes in Index
+RevertFailureDialog_ReasonChangesInWorkingDirectory=Local Changes in Working Directory
+RevertFailureDialog_ReasonDeleteFailure=Unable to Delete
+RevertFailureDialog_Title=Revert Failed
+RevertHandler_AlreadyRevertedMessage=The change has already been reverted
+RevertHandler_JobName=Reverting Commit {0}
+RevertHandler_NoRevertTitle=No revert performed
+RevertOperation_Failed=The revert failed
+RevertOperation_InternalError=An internal error occurred
+
+SelectUriWiazrd_Title=Select a URI
+SimpleConfigurePushDialog_UseUriForPushUriMessage=No Push URIs, will use URI {0}
+SimpleConfigurePushDialog_WindowTitle=Configure Push
+SimpleConfigurePushDialog_AddPushUriButton=&Add...
+SimpleConfigurePushDialog_AddRefSpecButton=A&dd...
+SimpleConfigurePushDialog_AdvancedButton=&Advanced
+SimpleConfigurePushDialog_BranchLabel=Branch:
+SimpleConfigurePushDialog_ChangePushUriButton=C&hange...
+SimpleConfigurePushDialog_ChangeRefSpecButton=M&odify...
+SimpleConfigurePushDialog_ChangeUriButton=&Change...
+SimpleConfigurePushDialog_CopyRefSpecButton=C&opy
+SimpleConfigurePushDialog_DefaultPushNoRefspec=No Push Refspec, will push currently checked out branch instead.
+SimpleConfigurePushDialog_DeletePushUriButton=De&lete
+SimpleConfigurePushDialog_DeleteRefSpecButton=Dele&te
+SimpleConfigurePushDialog_DeleteUriButton=Re&move
+SimpleConfigurePushDialog_DetachedHeadMessage=Detached HEAD
+SimpleConfigurePushDialog_DialogMessage=In order to use a remote for push, you must specify at least one URI and at least one ref mapping
+SimpleConfigurePushDialog_DialogTitle=Configure push for remote ''{0}''
+SimpleConfigurePushDialog_DryRunButton=Dr&y-Run
+SimpleConfigurePushDialog_EditAdvancedButton=Ad&vanced...
+SimpleConfigurePushDialog_EmptyClipboardDialogMessage=The clipboard is empty
+SimpleConfigurePushDialog_EmptyClipboardDialogTitle=Nothing to Paste
+SimpleConfigurePushDialog_InvalidRefDialogMessage=Refspec {0} does not appear to be valid, do you still want to add it?
+SimpleConfigurePushDialog_InvalidRefDialogTitle=Invalid Ref
+SimpleConfigurePushDialog_MissingUriMessage=Please provide at least one URI
+SimpleConfigurePushDialog_NoRefSpecDialogMessage=The contents of the clipboard does not appear to be a refspec
+SimpleConfigurePushDialog_NoRefSpecDialogTitle=Not a Refspec
+SimpleConfigurePushDialog_PasteRefSpecButton=Pa&ste
+SimpleConfigurePushDialog_PushUrisLabel=Push URIs
+SimpleConfigurePushDialog_RefMappingGroup=Ref mappings
+SimpleConfigurePushDialog_RefSpecLabel=&Refspec:
+SimpleConfigurePushDialog_RemoteGroupTitle=Push Configuration for Remote ''{0}''
+SimpleConfigurePushDialog_RepositoryLabel=Repository:
+SimpleConfigurePushDialog_ReusedOriginWarning=Note that remote ''{0}'' is used from {1} other branches (see tooltip for a list)
+SimpleConfigurePushDialog_RevertButton=Re&vert
+SimpleConfigurePushDialog_SaveAndPushButton=Save and Push
+SimpleConfigurePushDialog_SaveButton=Save
+SimpleConfigurePushDialog_UriGroup=URI
+SimpleConfigurePushDialog_URILabel=&URI:
+SkipRebaseCommand_CancelDialogMessage=The skip operation was canceled
+SkipRebaseCommand_JobName=Skipping Rebase
+
+ValidationUtils_CanNotResolveRefMessage=Can not resolve {0}
+ValidationUtils_InvalidRefNameMessage={0} is not a valid name for a ref
+ValidationUtils_RefAlreadyExistsMessage=Ref {0} already exists
+ValidationUtils_RefNameConflictsWithExistingMessage=Name conflicts with existing refs: {0}
+ValidationUtils_PleaseEnterNameMessage=Please enter a name
+
+GitMergeEditorInput_CalculatingDiffTaskName=Calculating Differences
+GitMergeEditorInput_CheckingResourcesTaskName=Checking resources
+GitMergeEditorInput_MergeEditorTitle=Repository ''{0}'': Merging ''{1}'' into ''{2}''
+GitMergeEditorInput_WorkspaceHeader=Workspace Version
+GitModelIndex_index=<staged changes>
+
+GitModelWorkingTree_workingTree=<working tree>
+
+EgitUiEditorUtils_openFailed=Opening editor failed
+
+SimpleConfigureFetchDialog_AddRefSpecButton=A&dd...
+SimpleConfigureFetchDialog_BranchLabel=Branch:
+SimpleConfigureFetchDialog_ChangeRefSpecButton=M&odify...
+SimpleConfigureFetchDialog_ChangeUriButton=&Change...
+SimpleConfigureFetchDialog_CopyRefSpecButton=C&opy
+SimpleConfigureFetchDialog_DeleteRefSpecButton=Dele&te
+SimpleConfigureFetchDialog_DeleteUriButton=Re&move
+SimpleConfigureFetchDialog_DetachedHeadMessage=Detached HEAD
+SimpleConfigureFetchDialog_DialogMessage=In order to use a remote for fetch, you must specify a URI and at least one ref mapping
+SimpleConfigureFetchDialog_DialogTitle=Configure fetch for remote ''{0}''
+SimpleConfigureFetchDialog_DryRunButton=Dr&y-Run
+SimpleConfigureFetchDialog_EditAdvancedButton=Ad&vanced...
+SimpleConfigureFetchDialog_EmptyClipboardMessage=The clipboard is empty
+SimpleConfigureFetchDialog_InvalidRefDialogMessage=Refspec {0} does not appear to be valid, do you still want to add it?
+SimpleConfigureFetchDialog_InvalidRefDialogTitle=Invalid Ref
+SimpleConfigureFetchDialog_MissingMappingMessage=Please provide a ref mapping
+SimpleConfigureFetchDialog_MissingUriMessage=Please provide a URI
+SimpleConfigureFetchDialog_NothingToPasteMessage=Nothing to paste
+SimpleConfigureFetchDialog_NotRefSpecDialogMessage=The contents of the clipboard does not appear to be a refspec
+SimpleConfigureFetchDialog_NotRefSpecDialogTitle=Not a Refspec
+SimpleConfigureFetchDialog_PateRefSpecButton=&Paste
+SimpleConfigureFetchDialog_RefMappingGroup=Ref mappings
+SimpleConfigureFetchDialog_RefSpecLabel=&RefSpec:
+SimpleConfigureFetchDialog_RemoteGroupHeader=Fetch configuration for remote ''{0}''
+SimpleConfigureFetchDialog_RepositoryLabel=Repository:
+SimpleConfigureFetchDialog_ReusedRemoteWarning=Note that remote ''{0}'' is used from {1} other branches (see tooltip for a list)
+SimpleConfigureFetchDialog_RevertButton=Re&vert
+SimpleConfigureFetchDialog_SaveAndFetchButton=Save and Fetch
+SimpleConfigureFetchDialog_SaveButton=Save
+SimpleConfigureFetchDialog_UriLabel=&URI:
+SimpleConfigureFetchDialog_WindowTitle=Configure Fetch
+SimpleFetchActionHandler_NothingToFetchDialogMessage=Can not fetch anything: the currently checked-out branch is based on a local branch
+SimpleFetchActionHandler_NothingToFetchDialogTitle=Nothing to Fetch
+SimpleFetchRefSpecWizard_WizardTitle=Adding a Refspec for Fetch
+SimplePushActionHandler_NothingToPushDialogMessage=Can not push anything: the currently checked-out branch is based on a local branch
+SimplePushActionHandler_NothingToPushDialogTitle=Nothing to Push
+SimplePushSpecPage_message=Select target to push {0} to
+SimplePushSpecPage_pushAheadInfo={0} is {1} commits ahead of {2}
+SimplePushSpecPage_TargetRefName=Target Ref Name:
+SimplePushSpecPage_title=Select push destination
+SwitchToMenu_NewBranchMenuLabel=&New Branch...
+SwitchToMenu_OtherMenuLabel=&Other...
+GitActionContributor_ExpandAll=Expand All
+GitActionContributor_Push=Push
+GitActionContributor_Pull=Pull
+GitLabelProvider_UnableToRetrieveLabel=Unable to retrieve label for {0}
+GitVariableResolver_InternalError=Internal error
+GitVariableResolver_NoSelectedResource=No selected resource
+GitVariableResolver_VariableReferencesNonExistentResource=Variable references non-existent resource : {0}
+
+OpenWorkingFileAction_text=&Open
+OpenWorkingFileAction_tooltip=Open working file
+OpenWorkingFileAction_openWorkingFileShellTitle=Problems Opening Working File
+
+StagingView_UnstagedChanges=Unstaged Changes ({0})
+StagingView_ShowFileNamesFirst=Show File Names First
+StagingView_StagedChanges=Staged Changes ({0})
+StagingView_CommitMessage=Commit Message
+StagingView_Committer=Committer:
+StagingView_Author=Author:
+StagingView_Ammend_Previous_Commit=Amend Previous Commit
+StagingView_Add_Signed_Off_By=Add Signed-off-by
+StagingView_Add_Change_ID=Add Change-Id
+StagingView_Commit=Commit
+StagingView_CommitToolTip=Commit ({0})
+StagingView_CommitAndPush=Commit and Push
+StagingView_checkoutFailed=Checking out files failed
+StagingView_commitFailed=Commit failed
+StagingView_committingNotPossible=Committing is not possible
+StagingView_headCommitChanged=\# WARNING: head commit changed in the meantime
+StagingView_noStagedFiles=There are no staged files
+StagingView_NoSelectionTitle=No Repository Selected
+StagingView_OpenNewCommits=Open New Commits
+StagingView_ColumnLayout=Column Layout
+StagingView_Refresh=Refresh
+StagingView_LinkSelection=Link with Editor and Selection
+StagingView_exceptionTitle=Refresh Error
+StagingView_exceptionMessage=Errors occurred while applying processing change notifications.
+StagingView_replaceWithFileInGitIndex=Replace with File in Git Index
+StagingView_replaceWithHeadRevision=Replace with HEAD Revision
+StagingView_UnstageItemMenuLabel=Remove from Git Index
+StagingView_StageItemMenuLabel=Add to Git Index
+StagingView_IgnoreItemMenuLabel=Ignore
+StagingView_DeleteItemMenuLabel=Delete
+StagingViewContentProvider_SubmoduleError=Unhandled exception while analyzing submodules
+StashApplyCommand_applyFailed=Applying stashed commit ''{0}'' failed due to ''{1}''
+StashApplyCommand_jobTitle=Apply changes from stashed commit ''{0}''
+StashCreateCommand_jobTitle=Stashing local changes
+StashCreateCommand_messageEnterCommitMessage=Enter stash commit message (optional):
+StashCreateCommand_messageNoChanges=The repository does not contain any local changes to stash.
+StashCreateCommand_stashFailed=Stash create error
+StashCreateCommand_titleEnterCommitMessage=Commit Stash
+StashCreateCommand_titleNoChanges=No Changes
+StashDropCommand_confirmMessage=Are you sure you want to delete stashed commit stash@'{'{0}'}'?
+StashDropCommand_confirmTitle=Confirm Stashed Commit Deletion
+StashDropCommand_dropFailed=Dropping stashed commit ''{0}'' failed
+StashDropCommand_jobTitle=Dropping stashed commit ''{0}''
+SubmoduleAddCommand_AddError=Submodule add error
+SubmoduleAddCommand_JobTitle=Creating submodule ''{0}'' from ''{1}''
+SubmodulePathWizardPage_ErrorPathMustBeEmpty=Path must be an empty or non-existent directory
+SubmodulePathWizardPage_Message=Enter relative path to submodule
+SubmodulePathWizardPage_PathLabel=Submodule Path:
+SubmodulePathWizardPage_Title=Submodule Path
+SubmoduleSyncCommand_SyncError=Submodule configuration sync error
+SubmoduleSyncCommand_Title=Synchronized submodule configuration
+SubmoduleUpdateCommand_Title=Updating submodules
+SubmoduleUpdateCommand_UpdateError=Submodule update error
+
+SynchronizeWithMenu_custom=&Custom...
+SynchronizeFetchJob_JobName=Fetching changes before synchronization launch
+SynchronizeFetchJob_TaskName=Fetching changes for synchronization
+SynchronizeFetchJob_SubTaskName=Fetching changes from {0}
+SynchronizeFetchJob_FetchFailedTitle=Fetch from {0} Failed
+SynchronizeFetchJob_FetchFailedMessage=Fetch operation failed.\n\nSychronization will be continued based on data that are currently in repository.\n\nYou can disable fetching changes before synchronization in preferences:\nTeam > Git > {0}
+
+GitModelSynchonize_fetchGitDataJobName=Fetching data from git
+
+FetchChangeFromGerritCommand_noRepositorySelectedTitle=No Git project was selected
+FetchChangeFromGerritCommand_noRepositorySelectedMessage=To be able to fetch changes from Gerrit you need to select a project which is shared with a Git repository and which is configured with Gerrit as a remote repository
+
+RebasePulldownAction_Continue=&Continue
+RebasePulldownAction_Skip=&Skip
+RebasePulldownAction_Abort=&Abort
+
+SynchronizeCommand_jobName=Synchronizing {0} ...
+GitOpenInCompareAction_cannotRetrieveCommitWithId=Cannot retrieve commit with id {0} from repository {1}
+
+CloneFailureDialog_tile=Transport Error
+CloneFailureDialog_dontShowAgain=Don't show this dialog again
+CloneFailureDialog_checkList={0}\n\nPlease check:\nNetwork Connection settings\nNetwork Connection -> SSH2 Eclipse preferences\n\nYou may also need to restart Eclipse after making changes in preferences.
+
+GarbageCollectCommand_jobTitle=Collect garbage in {0}
+GarbageCollectCommand_failed=Garbage collection in repository {0} failed
+
+RepositoryStatistics_Description=Description
+RepositoryStatistics_LooseObjects=Loose objects
+RepositoryStatistics_NrOfObjects=Number of objects
+RepositoryStatistics_NrOfPackfiles=Number of packfiles
+RepositoryStatistics_NrOfRefs=Number of refs
+RepositoryStatistics_SpaceNeededOnFilesystem=Space needed on filesystem
+RepositoryStatistics_PackedObjects=Packed objects
+
+GitModelSynchronizeParticipant_initialScopeName=Git
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/variables/GitVariableResolver.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/variables/GitVariableResolver.java
index 6a07621..58f7b45 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/variables/GitVariableResolver.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/variables/GitVariableResolver.java
@@ -20,8 +20,8 @@
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.variables.IDynamicVariable;
 import org.eclipse.core.variables.IDynamicVariableResolver;
-import org.eclipse.egit.core.project.RepositoryMapping;
-import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.core.internal.project.RepositoryMapping;
+import org.eclipse.egit.ui.internal.Activator;
 import org.eclipse.egit.ui.internal.UIText;
 import org.eclipse.jface.viewers.ISelection;
 import org.eclipse.jface.viewers.ISelectionProvider;
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties
deleted file mode 100644
index 8d24014..0000000
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/uitext.properties
+++ /dev/null
@@ -1,1673 +0,0 @@
-###############################################################################
-# Copyright (c) 2005, 2013 Shawn Pearce and others.
-# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Eclipse Public License v1.0
-# which accompanies this distribution, and is available at
-# http://www.eclipse.org/legal/epl-v10.html
-#
-# Contributors:
-#    Shawn Pearce - initial implementation
-#    Daniel Megert <daniel_megert@ch.ibm.com> - Escaped single quotes where needed
-#                                             - Removed unused entry
-#                                             - Added context menu to the Commit Editor's header text
-#    Markus Keller <markus_keller@ch.ibm.com> - Show the repository name in the title of the Pull Result dialog
-#    Daniel Megert <daniel_megert@ch.ibm.com> - Use correct syntax when a single ref was updated
-#    Gunnar Wagenknecht <gunnar@wagenknecht.org>
-###############################################################################
-AbortRebaseCommand_CancelDialogMessage=The abort operation was canceled
-AbortRebaseCommand_JobName=Aborting Rebase
-AbstractHistoryCommanndHandler_CouldNotGetRepositoryMessage=Could not get the repository from the history view
-AbstractHistoryCommanndHandler_NoInputMessage=Could not get the current input from the history view
-AbstractRebaseCommand_DialogTitle=Action Canceled
-AbstractReflogCommandHandler_NoInput=Could not get the current input from the Reflog View
-Activator_DefaultRepoFolderIsFile=The location {0} of the default repository folder is already used by a file
-Activator_DefaultRepoFolderNotCreated=Default repository folder {0} could not be created
-Activator_refreshingProjects=Refreshing Git managed projects
-Activator_refreshJobName=Git Repository Refresh
-Activator_repoScanJobName=Git Repository Change Scanner
-Activator_scanError=An error occurred while scanning for changes. Scanning aborted
-Activator_scanningRepositories=Scanning Git repositories for changes
-Activator_refreshFailed=Failed to refresh projects from index changes
-AddConfigEntryDialog_AddConfigTitle=Add a configuration entry
-AddConfigEntryDialog_ConfigKeyTooltip=Use "." to separate section/subsection/name, e.g. "core.bare", "remote.origin.url"
-AddConfigEntryDialog_DialogMessage=Please enter a key, e.g. "user.name" and a value
-AddConfigEntryDialog_EnterValueMessage=Please enter a value
-AddConfigEntryDialog_KeyComponentsMessage=The key must have two or three components separated by "."
-AddConfigEntryDialog_KeyLabel=&Key
-AddConfigEntryDialog_MustEnterKeyMessage=Please enter a key
-AddConfigEntryDialog_ValueLabel=&Value
-AddSubmoduleWizard_WindowTitle=Add Submodule
-AddToIndexAction_addingFiles=Adding Files to Git Index
-AddToIndexCommand_addingFilesFailed=Adding files failed
-RemoveFromIndexAction_removingFiles=Removing file from Git Index
-BlameInformationControl_Author=Author: {0} <{1}> {2}
-BlameInformationControl_Commit=Commit {0}
-BlameInformationControl_Committer=Committer: {0} <{1}> {2}
-AssumeUnchanged_assumeUnchanged=Assume Unchanged
-AssumeUnchanged_noAssumeUnchanged=No Assume Unchanged
-WizardProjectsImportPage_ImportProjectsTitle=Import Projects
-WizardProjectsImportPage_ImportProjectsDescription=Import projects from a Git repository
-WizardProjectsImportPage_ProjectsListTitle=&Projects:
-WizardProjectsImportPage_selectAll = &Select All
-WizardProjectsImportPage_deselectAll = &Deselect All
-WizardProjectsImportPage_SearchingMessage = Searching for projects
-WizardProjectsImportPage_ProcessingMessage = Processing results
-WizardProjectsImportPage_projectsInWorkspace = Some or all projects can not be imported because they already exist in the workspace
-WizardProjectsImportPage_CheckingMessage = Checking: {0}
-WizardProjectsImportPage_CreateProjectsTask = Creating Projects
-WizardProjectsImportPage_filterText = type filter text to filter unselected projects
-
-SecureStoreUtils_writingCredentialsFailed=Writing to secure store failed
-SelectResetTypePage_labelCurrentHead=Current HEAD:
-SelectResetTypePage_labelResettingTo=Resetting to:
-SelectResetTypePage_PageMessage=Select the type of reset to perform
-SelectResetTypePage_PageTitle=Reset {0}
-SelectResetTypePage_tooltipCurrentHead=The current HEAD ref
-SelectResetTypePage_tooltipResettingTo=The ref being reset to
-SharingWizard_windowTitle=Configure Git Repository
-SharingWizard_failed=Failed to initialize Git team provider.
-SharingWizard_MoveProjectActionLabel=Move Project
-ShowBlameHandler_errorMessage=Showing annotations failed
-ShowBlameHandler_JobName=Computing Blame Annotations
-
-GenerateHistoryJob_BuildingListMessage=Building commit list for ''{0}''...
-GenerateHistoryJob_CancelMessage=Reading commit list was canceled for ''{0}''
-GenerateHistoryJob_errorComputingHistory=Cannot compute Git history.
-GenerateHistoryJob_NoCommits=No commits for ''{0}''
-GenerateHistoryJob_taskFoundMultipleCommits=Found {0} commits
-GenerateHistoryJob_taskFoundSingleCommit=Found 1 commit
-GerritConfigurationPage_BranchTooltipHover=Press {0} to see a filtered list of branch names
-GerritConfigurationPage_ConfigureFetchReviewNotes=Fetch will be auto-configured to fetch review notes from Gerrit.
-GerritConfigurationPage_errorBranchName=Branch name is required
-GerritConfigurationPage_groupFetch=Fetch configuration
-GerritConfigurationPage_groupPush=Push configuration
-GerritConfigurationPage_labelDestinationBranch=&Destination branch:
-GerritConfigurationPage_PageDescription=Configure Gerrit Code Review properties for remote ''{0}'' of repository ''{1}''
-GerritConfigurationPage_pushUri=&Push URI
-GerritConfigurationPage_title=Gerrit Configuration
-GerritConfigurationPage_UserLabel=&User:
-
-EGitCredentialsProvider_errorReadingCredentials=Failed reading credentials from secure store
-EGitCredentialsProvider_FailedToClearCredentials=Failed to clear credentials for {0} stored in secure store
-EGitCredentialsProvider_question=Question
-EGitCredentialsProvider_information=Information
-CustomPromptDialog_provide_information_for=Provide information for {0}
-CustomPromptDialog_information_about=Information about {0}
-EgitUiUtils_CouldNotOpenEditorMessage=Could not open editor of type {0}
-ExistingOrNewPage_BrowseRepositoryButton=Br&owse...
-ExistingOrNewPage_CreateButton=&Create Repository
-ExistingOrNewPage_CreateRepositoryButton=Create...
-ExistingOrNewPage_CreationInWorkspaceWarningTooltip=When checked, this wizard will try to find or create a repository in the parent folder hierarchy of the selected projects.\nTypically, newly created projects are located in the Eclipse workspace, thus repositories created this way\nwould also end up in the Eclipse workspace.\nThis is not recommended for several reasons explained in the EGit user guide.
-ExistingOrNewPage_CurrentLocationColumnHeader=Current Location
-ExistingOrNewPage_title=Configure Git Repository
-ExistingOrNewPage_description=Select repository location
-ExistingOrNewPage_DescriptionExternalMode=Select an existing repository or create a new one
-ExistingOrNewPage_ErrorFailedToCreateRepository=Failed to create repository {0}
-ExistingOrNewPage_ErrorFailedToRefreshRepository=Failed to refresh project after creating repository at {0}
-ExistingOrNewPage_ExistingRepositoryLabel=&Repository:
-ExistingOrNewPage_ExistingTargetErrorMessage=Target location for project {0} already exists, can not move project
-ExistingOrNewPage_FailedToDetectRepositoryMessage=Failed to detect which repository to use
-ExistingOrNewPage_FolderWillBeCreatedMessage=Folder {0} does not exist in working directory, will be created
-ExistingOrNewPage_HeaderLocation=Location
-ExistingOrNewPage_HeaderProject=Project
-ExistingOrNewPage_HeaderRepository=Repository
-ExistingOrNewPage_InternalModeCheckbox=&Use or create repository in parent folder of project
-ExistingOrNewPage_NestedProjectErrorMessage=Can not move project {0} to target location {1}, as this location overlaps with location {2}, which contains a .project file
-ExistingOrNewPage_NewLocationTargetHeader=Target Location
-ExistingOrNewPage_NoRepositorySelectedMessage=No repository selected
-ExistingOrNewPage_ProjectNameColumnHeader=Project
-ExistingOrNewPage_RelativePathLabel=&Path within repository:
-ExistingOrNewPage_RepoCreationInWorkspaceCreationWarning=Creation of repositories in the Eclipse workspace is not recommended
-ExistingOrNewPage_SymbolicValueEmptyMapping=<empty repository mapping>
-ExistingOrNewPage_WorkingDirectoryLabel=Working directory:
-ExistingOrNewPage_WrongPathErrorDialogMessage=The selected path is not a child of the repository working tree
-ExistingOrNewPage_WrongPathErrorDialogTitle=Wrong Path
-
-GitCloneSourceProviderExtension_Local=Local
-GitCloneWizard_abortingCloneMsg=A partial or complete clone was already made. Do you want to delete it?
-GitCloneWizard_abortingCloneTitle=Aborting Clone
-GitCloneWizard_title=Clone Git Repository
-GitCloneWizard_jobImportProjects=Importing projects from ''{0}''
-GitCloneWizard_jobName=Cloning from {0}
-GitCloneWizard_failed=Git repository clone failed.
-GitCloneWizard_errorCannotCreate=Cannot create directory {0}.
-GitCloneWizard_MissingNotesMessage=No review has been done yet for the Repository.\nPlease add the fetch refspec "refs/notes/review:refs/notes/review" later on.
-GitCloneWizard_MissingNotesTitle=Missing Review Notes
-GitDecoratorPreferencePage_bindingRepositoryNameFlag=Name and state of the repository (the default state will not be shown)
-GitDecoratorPreferencePage_iconsShowDirty=Dirty resources
-GitDocument_errorLoadCommit=Could not load commit {0} for {1} corresponding to {2} in {3}
-GitDocument_errorLoadTree=Could not load tree {0} for {1} corresponding to {2} in {3}
-GitDocument_errorRefreshQuickdiff=Failed to refresh Quick Diff
-GitDocument_errorResolveQuickdiff=Could not resolve Quick Diff baseline {0} corresponding to {1} in {2}
-GitHistoryPage_AllChangesInFolderHint=All changes of this resource's parent folder and its children
-GitHistoryPage_AllChangesInProjectHint=All changes of this resource's project and its children
-GitHistoryPage_AllChangesInRepoHint=All changes in the repository containing this resource
-GitHistoryPage_AllChangesOfResourceHint=Changes of this resource and its children only
-GitHistoryPage_AllInParentMenuLabel=All Changes in Parent &Folder
-GitHistoryPage_AllInParentTooltip=Show all changes in parent folder of the selected resource
-GitHistoryPage_AllInProjectMenuLabel=All Changes in &Project
-GitHistoryPage_AllInProjectTooltip=Show all changes in project containing the selected resource
-GitHistoryPage_AllInRepoMenuLabel=All Changes in &Repository
-GitHistoryPage_AllInRepoTooltip=Show all changes in repository containing the selected resource
-GitHistoryPage_AllOfResourceMenuLabel=All &Changes of Resource
-GitHistoryPage_AllOfResourceTooltip=Show all changes of selected resource and its children
-GitHistoryPage_CheckoutMenuLabel=&Checkout
-GitHistoryPage_CheckoutMenuLabel2=&Checkout...
-GitHistoryPage_CompareModeMenuLabel=Compare &Mode
-GitHistoryPage_ReuseCompareEditorMenuLabel=Reuse Compare &Editor
-GitHistoryPage_CompareWithCurrentHeadMenu=Compare with &HEAD
-GitHistoryPage_CompareWithEachOtherMenuLabel=Compare with &Each Other
-GitHistoryPage_CompareWithWorkingTreeMenuMenuLabel=Compare with &Workspace
-GitHistoryPage_CreateBranchMenuLabel=Create &Branch...
-GitHistoryPage_CreatePatchMenuLabel=Create &Patch...
-GitHistoryPage_CreateTagMenuLabel=Create &Tag...
-GitHistoryPage_cherryPickMenuItem=C&herry Pick
-GitHistoryPage_compareMode=Compare Mode
-GitHistoryPage_showAllBranches=Show All Branches and Tags
-GitHistoryPage_errorLookingUpPath=IO error looking up path {0} in {1}.
-GitHistoryPage_errorParsingHead=Cannot parse HEAD in: {0}
-GitHistoryPage_errorReadingAdditionalRefs=Cannot read additional references for repository {0}
-GitHistoryPage_errorSettingStartPoints=Cannot set start points for repository {0}
-GitHistoryPage_fileNotFound=File not Found
-GitHistoryPage_notContainedInCommits=File {0} is not contained in the commits: {1}
-GitHistoryPage_FileNotInCommit={0} not in {1}
-GitHistoryPage_FileOrFolderPartOfGitDirMessage=File or folder {0} is part of the repository''s Git directory
-GitHistoryPage_FileType=File
-GitHistoryPage_FindMenuLabel=Find &Toolbar
-GitHistoryPage_FindTooltip=Show Find Toolbar
-GitHistoryPage_FolderType=Folder
-GitHistoryPage_MultiResourcesType={0} resources
-GitHistoryPage_NoInputMessage=No input
-GitHistoryPage_openFailed=Opening Editor Failed
-GitHistoryPage_OpenInTextEditorLabel=Open in Text &Editor
-GitHistoryPage_OpenMenuLabel=&Open
-GitHistoryPage_PreferencesLink=<a>Preferences...</a>
-GitHistoryPage_ProjectType=Project
-GitHistoryPage_QuickdiffMenuLabel=&Quick Diff
-GitHistoryPage_RefreshMenuLabel=&Refresh
-GitHistoryPage_RepositoryNamePattern=Repository: {0}
-GitHistoryPage_ResetBaselineToHeadMenuLabel=Reset Baseline to &Current Revision (HEAD)
-GitHistoryPage_ResetBaselineToParentOfHeadMenuLabel=Reset Baseline to &Previous Revision (HEAD^)
-GitHistoryPage_ResetHardMenuLabel=&Hard (HEAD, Index, and Working Directory)
-GitHistoryPage_ResetMenuLabel=&Reset
-GitHistoryPage_ResetMixedMenuLabel=&Mixed (HEAD and Index)
-GitHistoryPage_ResetSoftMenuLabel=&Soft (HEAD Only)
-GitHistoryPage_revertMenuItem=Revert Commit
-GitHistoryPage_mergeMenuItem=Merge
-GitHistoryPage_rebaseMenuItem=Rebase on Top of
-GitHistoryPage_SetAsBaselineMenuLabel=&Set as Baseline
-GitHistoryPage_ShowAdditionalRefsMenuLabel=&Additional Refs
-GitHistoryPage_ShowAllBranchesMenuLabel=All &Branches and Tags
-GitHistoryPage_FollowRenames=&Follow Renames
-GitHistoryPage_FilterSubMenuLabel=&Filter
-GitHistoryPage_IncompleteListTooltip=Not all commits are shown, the limit may be exceeded or the job building the list may have been aborted
-GitHistoryPage_InRevisionCommentSubMenuLabel=&In Revision Comment
-GitHistoryPage_ListIncompleteWarningMessage=The list is incomplete
-GitHistoryPage_pushCommit=Push Commit...
-GitHistoryPage_ShowSubMenuLabel=&Show
-GitHistoryPage_toggleEmailAddresses=&E-mail Addresses
-GitPreferenceRoot_automaticallyEnableChangesetModel=Automatically enable commit &grouping in Git synchronizations
-GitPreferenceRoot_BlameGroupHeader=Blame Annotations
-GitPreferenceRoot_BlameIgnoreWhitespaceLabel=Ignore whitespace changes
-GitPreferenceRoot_fetchBeforeSynchronization=Always launch fetch before synchronization
-GitPreferenceRoot_CloningRepoGroupHeader=Cloning repositories
-GitPreferenceRoot_DefaultRepoFolderLabel=Default repository &folder:
-GitPreferenceRoot_DefaultRepoFolderTooltip=This folder will be suggested as parent folder when cloning a remote repository
-GitPreferenceRoot_DefaultRepoFolderVariableButton=&Variable...
-GitPreferenceRoot_HistoryGroupHeader=History view
-GitPreferenceRoot_MergeGroupHeader=Merge
-GitPreferenceRoot_MergeMode_0_Label=Prompt when starting tool
-GitPreferenceRoot_MergeMode_1_Label=Workspace (pre-merged by Git)
-GitPreferenceRoot_MergeMode_2_Label=Last HEAD (unmerged)
-GitPreferenceRoot_MergeModeLabel=&Merge tool content:
-GitPreferenceRoot_MergeModeTooltip=Determines which content to be displayed on the left side of the merge tool
-GitPreferenceRoot_RemoteConnectionsGroupHeader=Remote connections
-GitPreferenceRoot_RepoChangeScannerGroupHeader=Automatic refresh
-GitPreferenceRoot_SecureStoreGroupLabel=Secure Store
-GitPreferenceRoot_SecureStoreUseByDefault=Store credentials in secure store by default
-GitPreferenceRoot_SynchronizeView=Synchronize view
-GitProjectPropertyPage_LabelBranch=Branch:
-GitProjectPropertyPage_LabelGitDir=Git directory:
-GitProjectPropertyPage_LabelId=HEAD:
-GitProjectPropertyPage_LabelState=Current state:
-GitProjectPropertyPage_LabelWorkdir=Working directory:
-GitProjectPropertyPage_UnableToGetCommit=Unable to load commit {0}
-GitProjectPropertyPage_ValueEmptyRepository=None (empty repository)
-GitProjectPropertyPage_ValueUnbornBranch=None (unborn branch)
-GitProjectsImportPage_NoProjectsMessage=No projects found
-GitProjectsImportPage_SearchForNestedProjects=Searc&h for nested projects
-
-CleanRepositoryPage_cleanDirs=Clean selected untracked files and directories
-CleanRepositoryPage_cleanFiles=Clean selected untracked files
-CleanRepositoryPage_cleaningItems=Cleaning selected items...
-CleanRepositoryPage_findingItems=Finding items to clean...
-CleanRepositoryPage_includeIgnored=Include ignored resources
-CleanRepositoryPage_message=Select items to clean
-CleanRepositoryPage_title=Clean Repository
-ClearCredentialsCommand_clearingCredentialsFailed=Clearing credentials failed.
-CheckoutConflictDialog_conflictMessage=The files shown below have uncommitted changes which would be lost by the selected operation.\n\nEither commit the changes to the repository or discard the changes by resetting the current branch.
-CheckoutDialog_Message=Select a ref and choose action to execute
-CheckoutDialog_OkCheckout=&Checkout
-CheckoutDialog_Title=Checkout a ref or work with branches
-CheckoutDialog_WindowTitle=Branches
-CheckoutHandler_SelectBranchMessage=There is more than one branch for this commit. Please select the branch you want to check out.
-CheckoutHandler_SelectBranchTitle=Select a Branch for Checkout
-CherryPickHandler_NoCherryPickPerformedMessage=The change has already been included
-CherryPickHandler_NoCherryPickPerformedTitle=No cherry pick performed
-CherryPickHandler_CherryPickConflictsMessage=Cherry pick could not be completed automatically because of conflicts. Please resolve and commit.
-CherryPickHandler_CherryPickConflictsTitle=Cherry Pick Conflicts
-CherryPickHandler_CherryPickFailedMessage=Cherry pick failed
-CherryPickHandler_CouldNotDeleteFile=Could not delete file
-CherryPickHandler_ErrorMsgTemplate={0} {1}
-CherryPickHandler_IndexDirty=Index is dirty
-CherryPickHandler_JobName=Cherry Picking Commit {0}
-CherryPickHandler_ConfirmMessage=Are you sure you want to cherry pick commit ''{0}'' onto branch ''{1}''?
-CherryPickHandler_ConfirmTitle=Cherry Pick Commit
-CherryPickHandler_unknown=unknown
-CherryPickHandler_WorktreeDirty=File is modified
-CherryPickOperation_Failed=The cherry pick failed
-CherryPickOperation_InternalError=An internal error occurred
-CompareTargetSelectionDialog_CompareButton=&Compare
-CompareTargetSelectionDialog_CompareMessage=Select a branch, tag, or reference to compare the resource with
-CompareTargetSelectionDialog_CompareTitle=Compare ''{0}'' with a Branch, Tag, or Reference
-CompareTargetSelectionDialog_CompareTitleEmptyPath=Compare with a Branch, Tag, or Reference
-CompareTargetSelectionDialog_WindowTitle=Compare
-CompareTreeView_AnalyzingRepositoryTaskText=Analyzing repository
-CompareTreeView_ExpandAllTooltip=Expand all
-CompareTreeView_CollapseAllTooltip=Collapse all
-CompareTreeView_ComparingTwoVersionDescription=Comparing version {0} of {1} with {2}
-CompareTreeView_ComparingWorkspaceVersionDescription=Comparing workspace version of {0} with {1}
-CompareTreeView_EqualFilesTooltip=Show files with equal content
-CompareTreeView_IndexVersionText=Index
-CompareTreeView_ItemNotFoundInVersionMessage={0} not found in {1}
-CompareTreeView_MultipleResourcesHeaderText=Multiple resources
-CompareTreeView_NoDifferencesFoundMessage=No differences found for the current selection and settings
-CompareTreeView_NoInputText=No input
-CompareTreeView_RepositoryRootName=Repository root
-CompareTreeView_WorkspaceVersionText=Workspace
-CompareUtils_errorGettingEncoding=Getting encoding failed
-CompareUtils_errorGettingHeadCommit=Getting HEAD commit failed
-CompareWithIndexAction_FileNotInIndex={0} not in index
-
-RebaseCurrentRefCommand_RebaseCanceledMessage=The rebase operation was canceled
-RebaseCurrentRefCommand_RebaseCanceledTitle=Rebase Canceled
-RebaseCurrentRefCommand_RebasingCurrentJobName=Rebasing Branch {0}
-RebaseCurrentRefCommand_ErrorGettingCurrentBranchMessage=Error getting the branch to rebase
-RebaseResultDialog_Aborted=Rebase was aborted
-RebaseResultDialog_AbortRebaseRadioText=&Abort rebase
-RebaseResultDialog_ActionGroupTitle=Action to perform
-RebaseResultDialog_CommitIdLabel=&Id:
-RebaseResultDialog_CommitMessageLabel=&Message:
-RebaseResultDialog_Conflicting=Rebase was stopped due to {0} conflicting files
-RebaseResultDialog_ConflictListFailureMessage=Error getting the list of conflicts
-RebaseResultDialog_DetailsGroup=Applying commit:
-RebaseResultDialog_DialogTitle=Rebase Result
-RebaseResultDialog_DiffDetailsLabel=&Files with rebase conflicts:
-RebaseResultDialog_DoNothingRadioText=Do nothing (return to the &workbench)
-RebaseResultDialog_FastForward=Rebase advanced HEAD fast-forward
-RebaseResultDialog_Failed=Rebase failed
-RebaseResultDialog_NextSteps=Next steps
-RebaseResultDialog_NextStepsAfterResolveConflicts=When you have resolved the conflicts run:\n- "Rebase > Continue"\n- or "Rebase > Abort"
-RebaseResultDialog_NextStepsDoNothing=- resolve the conflicts\n- then run "Rebase > Continue"\n- or "Rebase > Abort"
-RebaseResultDialog_NothingToCommit=No changes detected.\n\nIf there is nothing left to stage, chances are that something else\nalready introduced the same changes; you might want to skip this patch using "Rebase > Skip".
-RebaseResultDialog_notInWorkspace=<not in workspace>
-RebaseResultDialog_notInWorkspaceMessage=Some conflicting files are not part of the workspace. Open Staging View and launch a text editor to edit each conflicting file.
-RebaseResultDialog_notShared=<not shared>
-RebaseResultDialog_notSharedMessage=Some conflicting files reside in projects not shared with Git. Please share the related projects with Git.
-RebaseResultDialog_SkipCommitButton=&Skip this commit and continue rebasing the next commits
-RebaseResultDialog_StartMergeRadioText=Start Merge &Tool to resolve conflicts
-RebaseResultDialog_StatusLabel=Result status: {0}
-RebaseResultDialog_Stopped=Rebase stopped with conflicts
-RebaseResultDialog_SuccessfullyFinished=Rebase finished successfully
-RebaseResultDialog_ToggleShowButton=Don't show this confirmation dialog again
-RebaseResultDialog_UpToDate=Rebase did nothing, HEAD was already up-to-date
-RebaseTargetSelectionDialog_DialogMessage=Select a branch other than the currently checked out branch
-RebaseTargetSelectionDialog_DialogMessageWithBranch=Select a branch other than the ''{0}'' branch
-RebaseTargetSelectionDialog_DialogTitle=Rebase the currently checked out branch onto another branch
-RebaseTargetSelectionDialog_DialogTitleWithBranch=Rebase the ''{0}'' branch onto another branch
-RebaseTargetSelectionDialog_RebaseButton=&Rebase
-RebaseTargetSelectionDialog_RebaseTitle=Rebase ''{0}''
-RebaseTargetSelectionDialog_RebaseTitleWithBranch=Rebase ''{0}''
-ReplaceTargetSelectionDialog_ReplaceButton=&Replace
-ReplaceTargetSelectionDialog_ReplaceMessage=Select a branch, tag, or reference to replace the resource with
-ReplaceTargetSelectionDialog_ReplaceTitle=Replace ''{0}'' with a Branch, Tag, or Reference
-ReplaceTargetSelectionDialog_ReplaceTitleEmptyPath=Replace with a Branch, Tag, or Reference
-ReplaceTargetSelectionDialog_ReplaceWindowTitle=Replace
-ReplaceWithPreviousActionHandler_NoParentCommitDialogMessage=No previous revision of {0} could be found in the repository.
-ReplaceWithPreviousActionHandler_NoParentCommitDialogTitle=Previous revision not found
-RepositoryAction_errorFindingRepo=Could not find a repository associated with this project
-RepositoryAction_errorFindingRepoTitle=Cannot Find Repository
-RepositoryAction_multiRepoSelection=Cannot perform action on multiple repositories simultaneously.\n\nPlease select items from only one repository.
-RepositoryAction_multiRepoSelectionTitle=Multiple Repositories Selection
-RepositoryCommit_UserAndDate=\ ({0} on {1})
-RepositoryLocationPage_info=Select a location of Git Repositories
-RepositoryLocationPage_title=Select Repository Source
-RepositoryLocationContentProvider_errorProvidingRepoServer=Error on providing repository server infos
-
-RepositoryPropertySource_EditConfigurationTitle=Git Configuration Editor
-RepositoryPropertySource_EffectiveConfigurationAction=Effective Configuration
-RepositoryPropertySource_EffectiveConfigurationCategory=Effective configuration
-RepositoryPropertySource_ErrorHeader=Error
-RepositoryPropertySource_GlobalConfigurationCategory=Global configuration {0}
-RepositoryPropertySource_GlobalConfigurationMenu=Global Configuration
-RepositoryPropertySource_EditConfigButton=Edit...
-RepositoryPropertySource_EditorMessage=Edit the Git Configuration
-RepositoryPropertySource_RepositoryConfigurationButton=Repository Configuration
-RepositoryPropertySource_RepositoryConfigurationCategory=Repository configuration {0}
-RepositoryPropertySource_SelectModeTooltip=Select a configuration to display
-RepositoryPropertySource_SingleValueButton=Single Value
-RepositoryPropertySource_SuppressMultipleValueTooltip=Suppress display of multiple values
-RepositoryPropertySource_SystemConfigurationMenu=System Configuration
-
-RepositoryRemotePropertySource_ErrorHeader=Error
-RepositoryRemotePropertySource_FetchLabel=Remote Fetch Specification
-RepositoryRemotePropertySource_PushLabel=Remote Push Specification
-RepositoryRemotePropertySource_RemoteFetchURL_label=Remote Fetch URL
-RepositoryRemotePropertySource_RemotePushUrl_label=Remote Push URL
-
-RepositorySearchDialog_AddGitRepositories=Add Git Repositories
-RepositorySearchDialog_DeepSearch_button=&Look for nested repositories
-RepositorySearchDialog_RepositoriesFound_message={0} Git repositories found...
-RepositorySearchDialog_ScanningForRepositories_message=Searching
-RepositorySearchDialog_Search=&Search
-RepositorySearchDialog_SearchCriteriaGroup=Search criteria
-RepositorySearchDialog_SearchRecursiveToolTip=If this is checked, subdirectories of already found repositories will be searched recursively
-RepositorySearchDialog_SearchResultGroup=Search results
-RepositorySearchDialog_SearchTitle=Search and select Git repositories on your local file system
-RepositorySearchDialog_SearchTooltip=Performs a search with the current search criteria and updates the search result
-RepositorySearchDialog_SomeDirectoriesHiddenMessage={0} directories are hidden as they have already been added
-RepositorySearchDialog_DirectoryNotFoundMessage=Directory {0} does not exist
-RepositorySearchDialog_browse=&Browse...
-RepositorySearchDialog_CheckAllRepositories=Check All Repositories
-RepositorySearchDialog_directory=&Directory:
-RepositorySearchDialog_EnterDirectoryToolTip=Enter a local file system directory from which to start the search
-RepositorySearchDialog_errorOccurred=Error occurred
-RepositorySearchDialog_NoSearchAvailableMessage=No search results available for current search criteria, click Search button to update the list
-RepositorySearchDialog_NothingFoundMessage=No Git repositories found
-RepositorySearchDialog_searchRepositoriesMessage=Search for local Git repositories on the file system
-RepositorySearchDialog_UncheckAllRepositories=Uncheck All Repositories
-RepositorySelectionPage_BrowseLocalFile=Local File...
-RepositorySelectionPage_sourceSelectionTitle=Source Git Repository
-RepositorySelectionPage_sourceSelectionDescription=Enter the location of the source repository.
-RepositorySelectionPage_destinationSelectionTitle=Destination Git Repository
-RepositorySelectionPage_destinationSelectionDescription=Enter the location of the destination repository.
-RepositorySelectionPage_configuredRemoteChoice=Configured remote repository
-RepositorySelectionPage_errorValidating=Error validating {0}
-RepositorySelectionPage_uriChoice=Custom URI
-RepositorySelectionPage_groupLocation=Location
-RepositorySelectionPage_groupAuthentication=Authentication
-RepositorySelectionPage_groupConnection=Connection
-RepositorySelectionPage_promptURI=UR&I
-RepositorySelectionPage_promptHost=&Host
-RepositorySelectionPage_promptPath=&Repository path
-RepositorySelectionPage_promptUser=&User
-RepositorySelectionPage_promptPassword=&Password
-RepositorySelectionPage_promptScheme=Protoco&l
-RepositorySelectionPage_promptPort=Por&t
-RepositorySelectionPage_fieldRequired={0} required for {1} protocol.
-RepositorySelectionPage_fieldNotSupported={0} not supported on {1} protocol.
-RepositorySelectionPage_fileNotFound={0} does not exist.
-RepositorySelectionPage_internalError=Internal error; consult Eclipse error log.
-RepositorySelectionPage_storeInSecureStore=Store in Secure Store
-RepositorySelectionPage_tip_file=Local repository
-RepositorySelectionPage_tip_ftp=FTP
-RepositorySelectionPage_tip_git=Git native transfer
-RepositorySelectionPage_tip_http=HTTP (smart or dumb)
-RepositorySelectionPage_tip_https=Secure HTTP (smart or dumb)
-RepositorySelectionPage_tip_sftp=Secure FTP
-RepositorySelectionPage_tip_ssh=Git over SSH (also known as git+ssh)
-RepositorySelectionPage_UriMustNotHaveTrailingSpacesMessage=URI must not have trailing spaces
-SoftResetToRevisionAction_softReset=Soft Reset
-SourceBranchPage_repoEmpty=Source Git repository is empty
-SourceBranchPage_title=Branch Selection
-SourceBranchPage_description=Select branches to clone from remote repository. Remote tracking \
-branches will be created to track updates for these branches in the remote repository.
-SourceBranchPage_branchList=Branches &of {0}:
-SourceBranchPage_selectAll=&Select All
-SourceBranchPage_selectNone=&Deselect All
-SourceBranchPage_errorBranchRequired=At least one branch must be selected.
-SourceBranchPage_cannotListBranches=Cannot list the available branches.
-SourceBranchPage_remoteListingCancelled=Operation canceled
-SourceBranchPage_cannotCreateTemp=Couldn't create temporary repository.
-SourceBranchPage_CompositeTransportErrorMessage={0}:\n{1}
-SourceBranchPage_AuthFailMessage={0}:\nInvalid password or missing SSH key.
-
-CloneDestinationPage_title=Local Destination
-CloneDestinationPage_description=Configure the local storage location for {0}.
-CloneDestinationPage_groupDestination=Destination
-CloneDestinationPage_groupConfiguration=Configuration
-CloneDestinationPage_groupProjects=Projects
-CloneDestinationPage_promptDirectory=&Directory
-CloneDestinationPage_promptInitialBranch=Initial branc&h
-CloneDestinationPage_promptRemoteName=Remote na&me
-CloneDestinationPage_browseButton=Bro&wse
-CloneDestinationPage_cloneSubmodulesButton=Clone &submodules
-CloneDestinationPage_DefaultRepoFolderTooltip=You can change the default parent folder in the Git preferences
-CloneDestinationPage_errorDirectoryRequired=Directory is required
-CloneDestinationPage_errorInitialBranchRequired=Initial branch is required
-CloneDestinationPage_errorNotEmptyDir={0} is not an empty directory.
-CloneDestinationPage_errorRemoteNameRequired=Remote name is required
-CloneDestinationPage_importButton=&Import all existing projects after clone finishes
-
-RefContentProposal_blob=blob
-RefContentProposal_branch=branch
-RefContentProposal_by=by
-RefContentProposal_commit=commit
-RefContentProposal_errorReadingObject=Unable to read object {0} for content proposal assistance
-RefContentProposal_tag=tag
-RefContentProposal_trackingBranch=tracking branch
-RefContentProposal_tree=tree
-RefContentProposal_unknownObject=locally unknown object
-ReflogView_DateColumnHeader=Date
-ReflogView_ErrorOnOpenCommit=Error opening commit
-ReflogView_MessageColumnHeader=Reflog Message
-ReflogView_CommitColumnHeader=Commit
-ReflogView_CommitMessageColumnHeader=Commit Message
-RefSelectionDialog_Messsage=Select a branch to show the reflog for
-RefSelectionDialog_Title=Reflog Branch Selection
-RefSpecDialog_AutoSuggestCheckbox=&Automatically suggest a name for the remote tracking branch
-RefSpecDialog_DestinationFetchLabel=&Tracking branch:
-RefSpecDialog_DestinationPushLabel=&Remote branch:
-RefSpecDialog_FetchMessage=Fetch uses the content of a branch or tag of the remote repository as source and updates a tracking branch of the local repository (the target)
-RefSpecDialog_FetchTitle=Create or Edit a Refspec for Fetch
-RefSpecDialog_ForceUpdateCheckbox=&Force update
-RefSpecDialog_GettingRemoteRefsMonitorMessage=Getting remote refs...
-RefSpecDialog_MissingDataMessage=Please provide both a source and destination
-RefSpecDialog_PushMessage=Push uses the content of a branch or tag of the local repository as source and updates a branch of the remote repository (the target)
-RefSpecDialog_PushTitle=Create or Edit a Refspec for Push
-RefSpecDialog_SourceBranchFetchLabel=&Remote branch or tag:
-RefSpecDialog_SourceBranchPushLabel=&Local branch:
-RefSpecDialog_SpecificationLabel=&Specification:
-RefSpecDialog_WindowTitle=Create or Edit a Refspec
-RefSpecPanel_clickToChange=[Click to change]
-RefSpecPanel_columnDst=Destination Ref
-RefSpecPanel_columnForce=Force Update
-RefSpecPanel_columnMode=Mode
-RefSpecPanel_columnRemove=Remove
-RefSpecPanel_columnSrc=Source Ref
-RefSpecPanel_creationButton=Add Spec
-RefSpecPanel_creationButtonDescription=Add this create/update specification to set of {0} specifications.
-RefSpecPanel_creationDst=Destination ref:
-RefSpecPanel_creationGroup=Add create/update specification
-RefSpecPanel_creationSrc=Source ref:
-RefSpecPanel_deletionButton=Add spec
-RefSpecPanel_deletionButtonDescription=Add this delete specification to set of push specifications.
-RefSpecPanel_deletionGroup=Add delete ref specification
-RefSpecPanel_deletionRef=Remote ref to delete:
-RefSpecPanel_dstFetchDescription=Local destination ref(s) to fetch to - create or update.
-RefSpecPanel_dstPushDescription=Remote destination ref(s) to push to - create or update.
-RefSpecPanel_dstDeletionDescription=Remote ref to delete.
-RefSpecPanel_fetch=fetch
-RefSpecPanel_fetchTitle=Fetch
-RefSpecPanel_forceAll=Force Update All Specs
-RefSpecPanel_forceAllDescription=Set force update setting to all specifications.
-RefSpecPanel_forceDeleteDescription=Delete specification is always unconditional.
-RefSpecPanel_forceFalseDescription=Allow only fast-forward update: old object must merge into new object.
-RefSpecPanel_forceTrueDescription=Allow non-fast-forward update: old object doesn't have to merge to new object.
-RefSpecPanel_modeDelete=Delete
-RefSpecPanel_modeDeleteDescription=This is a delete specification.
-RefSpecPanel_modeUpdate=Update
-RefSpecPanel_modeUpdateDescription=This is a create/update specification.
-RefSpecPanel_predefinedAll=Add All Branches Spec
-RefSpecPanel_predefinedAllDescription=Add specification covering all branches.
-RefSpecPanel_predefinedConfigured=Add Configured {0} Specs
-RefSpecPanel_predefinedConfiguredDescription=Add previously configured specifications for this configured remote (if available).
-RefSpecPanel_predefinedGroup=Add predefined specification
-RefSpecPanel_predefinedTags=Add All Tags Spec
-RefSpecPanel_predefinedTagsDescription=Add specification covering all tags.
-RefSpecPanel_push=push
-RefSpecPanel_pushTitle=Push
-RefSpecPanel_refChooseSome=choose/some/ref
-RefSpecPanel_refChooseSomeWildcard=choose/some/ref/*
-RefSpecPanel_refChooseRemoteName=choose_remote_name
-RefSpecPanel_removeAll=Remove All Specs
-RefSpecPanel_removeAllDescription=Remove all specifications.
-RefSpecPanel_removeDescription=Click to remove this specification.
-RefSpecPanel_specifications=Specifications for {0}
-RefSpecPanel_srcFetchDescription=Remote source ref(s) to fetch from.
-RefSpecPanel_srcPushDescription=Local source ref(s) to push from.
-RefSpecPanel_srcDeleteDescription=Delete specification always has an empty source ref.
-RefSpecPanel_validationDstInvalidExpression={0} is not a valid ref expression for destination.
-RefSpecPanel_validationDstRequired=Destination ref is required.
-RefSpecPanel_validationRefDeleteRequired=Ref name to delete is required.
-RefSpecPanel_validationRefDeleteWildcard=Delete ref cannot be a wildcard.
-RefSpecPanel_validationRefInvalidExpression={0} is not a valid ref expression.
-RefSpecPanel_validationRefInvalidLocal={0} is not a valid ref in local repository.
-RefSpecPanel_validationRefNonExistingRemote={0} does not exist in remote repository.
-RefSpecPanel_validationRefNonExistingRemoteDelete={0} already does not exist in remote repository.
-RefSpecPanel_validationRefNonMatchingLocal={0} does not match any ref in local repository.
-RefSpecPanel_validationRefNonMatchingRemote={0} does not match any ref in remote repository.
-RefSpecPanel_validationSpecificationsOverlappingDestination=Two or more specifications point to {0} (the same destination).
-RefSpecPanel_validationSrcUpdateRequired=Source ref is required for update/create specification.
-RefSpecPanel_validationWildcardInconsistent=Wildcard must be set either on both source and destination or on none of them.
-
-RefSpecPage_descriptionFetch=Select refs to fetch.
-RefSpecPage_descriptionPush=Select refs to push.
-RefSpecPage_errorDontMatchSrc=Specifications don't match any existing refs in source repository.
-RefSpecPage_errorTransportDialogMessage=Cannot get remote repository refs.
-RefSpecPage_errorTransportDialogTitle=Transport Error
-RefSpecPage_operationCancelled=Operation canceled.
-RefSpecPage_saveSpecifications=Save specifications in ''{0}'' configuration
-RefSpecPage_titleFetch=Fetch Ref Specifications
-RefSpecPage_titlePush=Push Ref Specifications
-RefSpecPage_annotatedTagsGroup=Annotated tags fetching strategy
-RefSpecPage_annotatedTagsAutoFollow=Automatically follow tags if we fetch the thing they point at
-RefSpecPage_annotatedTagsFetchTags=Always fetch tags, even if we do not have the thing it points at
-RefSpecPage_annotatedTagsNoTags=Never fetch tags, even if we have the thing it points at
-
-QuickDiff_failedLoading=Quick diff failed to obtain file data.
-
-ResetAction_errorResettingHead=Cannot reset HEAD now
-ResetAction_repositoryState=Repository state: {0}
-ResetAction_reset=Resetting to {0}
-ResetCommand_ResetFailureMessage=Reset failed
-ResetCommand_WizardTitle=Reset
-ResetQuickdiffBaselineHandler_NoTargetMessage=No reset target provided
-ResetTargetSelectionDialog_ResetButton=&Reset
-ResetTargetSelectionDialog_ResetConfirmQuestion=Resetting will overwrite any changes in your working directory.\n\nDo you want to continue?
-ResetTargetSelectionDialog_ResetQuestion=Confirm Reset
-ResetTargetSelectionDialog_ResetTitle=Reset: {0}
-ResetTargetSelectionDialog_ResetTypeGroup=Reset type
-ResetTargetSelectionDialog_ResetTypeHardButton=&Hard (HEAD, index, and working directory updated)
-ResetTargetSelectionDialog_ResetTypeMixedButton=&Mixed (HEAD and index updated)
-ResetTargetSelectionDialog_ResetTypeSoftButton=&Soft (HEAD updated)
-ResetTargetSelectionDialog_ResetTypeHEADHardButton=&Hard (index and working directory updated)
-ResetTargetSelectionDialog_ResetTypeHEADMixedButton=&Mixed (index updated)
-ResetTargetSelectionDialog_SelectBranchForResetMessage=Select a branch to reset the current branch to
-ResetTargetSelectionDialog_WindowTitle=Reset
-ResourceHistory_MaxNumCommitsInList=Maximum number of commits to &show:
-ResourceHistory_ShowTagSequence=&Tag sequence
-ResourceHistory_toggleRelativeDate=Relative &Dates
-ResourceHistory_toggleShowNotes=&Notes History
-ResourceHistory_toggleCommentWrap=&Wrap Comments
-ResourceHistory_toggleCommentFill=Fill &Paragraphs
-ResourceHistory_toggleRevDetail=&Revision Details
-ResourceHistory_toggleRevComment=Revision C&omment
-
-HardResetToRevisionAction_hardReset=Hard Reset
-HistoryPage_authorColumn=Author
-HistoryPage_authorDateColumn=Authored Date
-HistoryPage_refreshJob=Reading history from Git repository ''{0}''
-
-HistoryPage_findbar_find=Find:
-HistoryPage_findbar_next=Next
-HistoryPage_findbar_previous=Previous
-HistoryPage_findbar_ignorecase=Ignore Case
-HistoryPage_findbar_commit=Id
-HistoryPage_findbar_comments=Comments
-HistoryPage_findbar_author=Author
-HistoryPage_findbar_committer=Committer
-HistoryPage_findbar_changeto_commit=Change to Id
-HistoryPage_findbar_changeto_comments=Change to Comments
-HistoryPage_findbar_changeto_author=Change to Author
-HistoryPage_findbar_changeto_committer=Change to Committer
-HistoryPage_findbar_exceeded=Results limit exceeded
-HistoryPage_findbar_notFound=String not found
-HistoryPreferencePage_toggleAllBranches=All &Branches and Tags
-HistoryPreferencePage_toggleAdditionalRefs=&Additional Refs
-HistoryPreferencePage_toggleEmailAddresses=&E-mail addresses in Author/Committer columns
-HistoryPreferencePage_MaxBranchLength=Maximum characters to show for a &branch:
-HistoryPreferencePage_MaxTagLength=&Maximum characters to show for a tag:
-HistoryPreferencePage_ShowGroupLabel=Show
-HistoryPreferencePage_ShowInRevCommentGroupLabel=Show in Revision Comment
-
-PullOperationUI_ConnectionProblem=Git connection problem.\
-\n\nMaybe you are offline or behind a proxy.\nCheck your network connection and proxy configuration.
-PullOperationUI_NotTriedMessage=Not tried
-PullOperationUI_PullCanceledWindowTitle=Pull Canceled
-PullOperationUI_PullErrorWindowTitle=Pull Error
-PullOperationUI_PullFailed=Pull Failed
-PullOperationUI_PullingMultipleTaskName=Pulling from Multiple Repositories
-PullOperationUI_PullingTaskName=Pulling Branch {0} - {1}
-PullOperationUI_PullOperationCanceledMessage=The pull operation was canceled
-PullResultDialog_NothingToFetchFromLocal=Nothing to fetch (the fetch source is the local Repository)
-PullResultDialog_DialogTitle=Pull Result for {0}
-PullResultDialog_FetchResultGroupHeader=Fetch Result
-PullResultDialog_MergeAlreadyUpToDateMessage=Nothing to update - everything up to date
-PullResultDialog_MergeResultGroupHeader=Update Result
-PullResultDialog_RebaseStatusLabel=Rebase status
-PullResultDialog_RebaseStoppedMessage=Rebase has stopped because of conflicts
-PushAction_wrongURIDescription=Remote repositories URIs configuration is corrupted.
-PushAction_wrongURITitle=Corrupted Configuration
-PushCommand_pushBranchTitle=Push Branch
-PushCommand_pushTagTitle=Push Tag
-PushCommitHandler_pushCommitTitle=Push Commit
-PushOperationUI_MultiRepositoriesDestinationString={0} repositories
-PushOperationUI_PushJobName=Push to {0}
-
-PushWizard_cantConnectToAny=Can''t connect to any repository: {0}
-PushWizard_cantPrepareUpdatesMessage=Can't resolve ref specifications locally (local refs changed?) or create tracking ref update.
-PushWizard_cantPrepareUpdatesTitle=Preparing Ref Updates Error
-PushWizard_cantSaveMessage=Couldn't save specified specifications in configuration file.
-PushWizard_cantSaveTitle=Configuration Storage Warning
-PushWizard_jobName=Pushing to {0}
-PushWizard_missingRefsMessage=Ref specifications don't match any source ref (local refs changed?).
-PushWizard_missingRefsTitle=Missing Refs Error
-PushWizard_unexpectedError=Unexpected error occurred.
-PushWizard_windowTitleDefault=Push to Another Repository
-PushWizard_windowTitleWithDestination=Push to: {0}
-
-CommitAction_amendCommit=No changed items were selected. Do you wish to amend the last commit?
-CommitAction_amendNotPossible=Commit/amend not possible. Possible causes\:\n\n- No changed items were selected\n- Multiple repositories selected\n- No repositories selected\n- No previous commits
-CommitAction_cannotCommit=Cannot commit now
-CommitAction_CommittingChanges=Committing changes
-CommitAction_CommittingFailed=Committing failed
-CommitAction_errorComputingDiffs=Error occurred computing diffs
-CommitAction_errorRetrievingCommit=Error occurred retrieving last commit
-CommitAction_noFilesToCommit=No files to commit
-CommitAction_repositoryState=Repository state: {0}
-CommitDialog_AddFileOnDiskToIndex=Add File on &Disk to Index
-CommitDialog_AddSOB=Add Signed-off-&by
-CommitDialog_AmendPreviousCommit=Am&end Previous Commit
-CommitDialog_Author=&Author:
-CommitDialog_Commit=&Commit
-CommitDialog_CommitAndPush=Commit and &Push
-CommitDialog_CommitChanges=Commit Changes
-CommitDialog_Committer=Committer:
-CommitDialog_CommitMessage=Commit message
-CommitDialog_DeselectAll=&Deselect All
-CommitDialog_ErrorAddingFiles=Error when adding files
-CommitDialog_ErrorInvalidAuthor=Invalid author
-CommitDialog_ErrorInvalidAuthorSpecified=Invalid author specified. Please use the form\:\nA U Thor <author@example.com>
-CommitDialog_ErrorInvalidCommitterSpecified=Invalid committer specified. Please use the form\:\nC O Mitter <committer@example.com>
-CommitDialog_ErrorMustEnterCommitMessage=You must enter a commit message
-CommitDialog_ErrorNoItemsSelected=No items selected
-CommitDialog_ErrorNoItemsSelectedToBeCommitted=No items are currently selected to be committed.
-CommitDialog_ErrorNoMessage=No message
-CommitDialog_SelectAll=&Select All
-CommitDialog_ShowUntrackedFiles=Show &Untracked Files
-CommitDialog_Status=Status
-CommitDialog_StatusAdded=Added
-CommitDialog_StatusAddedIndexDiff=Added, index diff
-CommitDialog_StatusAssumeUnchaged=Assume unchanged
-CommitDialog_StatusModified=Modified
-CommitDialog_StatusModifiedIndexDiff=Mod., index diff
-CommitDialog_StatusModifiedNotStaged=Mod., not staged
-CommitDialog_StatusRemoved=Removed
-CommitDialog_StatusRemovedNotStaged=Rem., not staged
-CommitDialog_StatusUnknown=Unknown
-CommitDialog_StatusUntracked=Untracked
-CommitDialog_StatusRemovedUntracked=Removed, Untracked
-CommitDialog_AddChangeIdLabel=Compute Change-Id for Gerrit Code Review
-CommitDialog_ConfigureLink=Preferences...
-CommitDialog_ContentAssist=Content assist available for previous commit messages and the files shown
-CommitDialog_Files=Files ({0}/{1})
-CommitDialog_Message=Enter commit message.
-CommitDialog_MessageNoFilesSelected=Select one or more files to commit
-CommitDialog_Path=Path
-CommitDialog_Title=Commit Changes to Git Repository
-CommitDialog_WrongTypeOfCommitMessageProvider=The extension used as CommitMessageProvider has the wrong type (it must implement org.eclipse.egit.ui.ICommitMessageProvider)
-
-SpellcheckableMessageArea_redo=Redo
-SpellcheckableMessageArea_showWhitespace=Show &Whitespace Characters
-SpellcheckableMessageArea_undo=Undo
-SpellCheckingMessageArea_copy=&Copy
-SpellCheckingMessageArea_cut=C&ut
-SpellCheckingMessageArea_paste=&Paste
-SpellCheckingMessageArea_selectAll=Select &All
-CommitMessageComponent_MessageInvalidAuthor=Invalid author specified. Example: A U Thor <author@example.com>
-CommitMessageComponent_MessageInvalidCommitter=Invalid committer specified. Example: C O Mitter <committer@example.com>
-CommitMessageComponent_AmendingCommitInRemoteBranch=The commit being amended has already been published to a remote branch.
-CommitMessageViewer_author=Author
-CommitMessageViewer_child=Child
-CommitMessageViewer_branches=Branches
-CommitMessageViewer_MoreBranches=\ and {0} more branches
-CommitMessageViewer_BuildDiffListTaskName=Building diffs for the selected files
-CommitMessageViewer_BuildDiffTaskName=Building diff for file {0}
-CommitMessageViewer_CanNotRenderDiffMessage=Can not render diff, as the current commit has multiple parents
-CommitMessageViewer_tags=Tags
-CommitMessageViewer_follows=Follows
-CommitMessageViewer_precedes=Precedes
-CommitMessageViewer_commit=commit
-CommitMessageViewer_committer=Committer
-CommitMessageViewer_FormattingMessageTaskName=Formatting commit message
-CommitMessageViewer_GettingNextTagTaskName=Getting next tag
-CommitMessageViewer_GettingPreviousTagTaskName=Getting previous tag
-CommitMessageViewer_parent=Parent
-CompareWithHeadActionHandler_NoHeadTitle=Compare With HEAD
-CompareWithHeadActionHandler_NoHeadMessage=Comparing is not possible, as there is not yet a HEAD commit.
-CompareWithIndexAction_errorOnAddToIndex=Error during adding to index
-CompareWithPreviousActionHandler_MessageRevisionNotFound=No previous revision of {0} could be found in the repository.
-CompareWithPreviousActionHandler_TaskGeneratingInput=Generating comparison with previous revision
-CompareWithPreviousActionHandler_TitleRevisionNotFound=Previous revision not found
-CompareWithRefAction_errorOnSynchronize=Error reading from repository while preparing input for compare operation.
-
-CompareUtils_errorCommonAncestor=Error finding common ancestor for {0} and {1}
-
-ConfirmationPage_cantConnectToAnyTitle=Can't Connect
-ConfirmationPage_cantConnectToAny=Can''t connect to any URI: {0}
-ConfirmationPage_description=Confirm following expected push result.
-ConfirmationPage_errorCantResolveSpecs=Can''t resolve ref specifications locally or create tracking ref update: {0}
-ConfirmationPage_errorInterrupted=Operation was interrupted.
-ConfirmationPage_errorRefsChangedNoMatch=Local refs changed, ref specifications don't match any source ref.
-ConfirmationPage_errorUnexpected=Unexpected error occurred: {0}
-ConfirmationPage_requireUnchangedButton=Push only if remote refs don't change in the mean time
-ConfirmationPage_showOnlyIfChanged=Show final report dialog only when it differs from this confirmation report
-ConfirmationPage_title=Push Confirmation
-CreateBranchDialog_DialogTitle=Create a Local Branch
-CreateBranchDialog_OKButtonText=Create Branch...
-CreateBranchDialog_SelectRefMessage=Select a branch, tag, or reference to base the new branch on
-CreateBranchDialog_WindowTitle=Create Branch
-CreateBranchPage_BranchNameLabel=&Branch name:
-CreateBranchPage_CheckingOutMessage=Checking out new branch...
-CreateBranchPage_CheckoutButton=&Checkout new branch
-CreateBranchPage_ChooseBranchAndNameMessage=Please choose a source branch and a name for the new branch
-CreateBranchPage_ChooseNameMessage=Please choose a name for the new branch
-CreateBranchPage_CreatingBranchMessage=Creating branch...
-CreateBranchPage_LocalBranchWarningText=You are creating a branch based on a local branch
-CreateBranchPage_LocalBranchWarningTooltip=Creating a branch that is based on a local branch is only useful for specific scenarios;\n in general, you should use branches that are based on a remote tracking branch
-CreateBranchPage_MergeRadioButton=&Merge
-CreateBranchPage_MissingSourceMessage=Please select a source branch
-CreateBranchPage_NoneRadioButton=&None
-CreateBranchPage_PullMergeTooltip=Fetch (unless the base branch is a local branch), then merge the branch with the fetch result
-CreateBranchPage_PullNoneTooltip=Do not fetch and update (pull will not work for this branch)
-CreateBranchPage_PullRebaseTooltip=Fetch (unless the base branch is a local branch), then rebase the branch onto the fetch result
-CreateBranchPage_PullStrategyGroupHeader=Pull strategy
-CreateBranchPage_PullStrategyTooltip=Here you can configure how pull will work for the new branch
-CreateBranchPage_RebaseRadioButton=&Rebase
-CreateBranchPage_SourceBranchLabel=&Source ref:
-CreateBranchPage_SourceBranchTooltip=The new branch will be created from this branch
-CreateBranchPage_SourceCommitLabel=&Source ref or commit:
-CreateBranchPage_SourceCommitTooltip=The branch will be created from this commit
-CreateBranchPage_Title=Create a new branch
-CreateBranchWizard_CreationFailed=Branch could not be created
-CreateBranchWizard_NewBranchTitle=Create Branch
-CreateRepositoryPage_BareCheckbox=&Create as bare repository
-CreateRepositoryPage_BrowseButton=&Browse...
-CreateRepositoryPage_DirectoryLabel=Parent &directory:
-CreateRepositoryPage_MissingNameMessage=Please choose a name
-CreateRepositoryPage_NotADirectoryMessage=Path {0} is not a directory
-CreateRepositoryPage_NotEmptyMessage=Directory {0} is not empty
-CreateRepositoryPage_PageMessage=Please determine the directory for the new repository
-CreateRepositoryPage_PageTitle=Create a New Git Repository
-CreateRepositoryPage_PleaseSelectDirectoryMessage=Please select a directory
-CreateRepositoryPage_PleaseUseAbsoluePathMessage=Please use an absolute path
-CreateRepositoryPage_RepositoryNameLabel=&Name:
-PushResultDialog_ConfigureButton=&Configure...
-PushResultTable_columnStatusRepo=Status: Repository #{0}
-PushResultTable_columnDst=Destination Ref
-PushResultTable_columnSrc=Source Ref
-PushResultTable_columnMode=Mode
-PushResultTable_MesasgeText=Message Details
-PushResultTable_statusUnexpected=Unexpected update status: {0}
-PushResultTable_statusConnectionFailed=[connection failed]
-PushResultTable_statusDetailChanged=remote ref object changed,\nnow it''s\: {0},\nnot expected\: {1}
-PushResultTable_refNonExisting=(non existing)
-PushResultTable_repository=Repository
-PushResultTable_statusDetailDeleted=old value: {0}
-PushResultTable_statusDetailNonFastForward=non-fast-forward
-PushResultTable_statusDetailNoDelete=remote side does not support deleting refs
-PushResultTable_statusDetailNonExisting=remote ref already does not exist
-PushResultTable_statusDetailForcedUpdate=forced update (non-fast-forward)
-PushResultTable_statusDetailFastForward=fast-forward
-PushResultTable_statusRemoteRejected=[remote rejected]
-PushResultTable_statusRejected=[rejected]
-PushResultTable_statusNoMatch=[no match]
-PushResultTable_statusUpToDate=[up to date]
-PushResultTable_statusOkDeleted=[deleted]
-PushResultTable_statusOkNewBranch=[new branch]
-PushResultTable_statusOkNewTag=[new tag]
-PushToGerritPage_BranchLabel=Gerrit &Branch:
-PushToGerritPage_ContentProposalHoverText=Press {0} to see a filtered list of branch names
-PushToGerritPage_Message=Select a Gerrit URI and branch name
-PushToGerritPage_MissingBranchMessage=Select a branch
-PushToGerritPage_MissingUriMessage=Select a URI
-PushToGerritPage_Title=Push the current HEAD from repository {0} to Gerrit
-PushToGerritPage_UriLabel=&URI:
-PushToGerritWizard_Title=Push the current HEAD to Gerrit
-ResultDialog_title=Push Results: {0}
-ResultDialog_label=Pushed to {0}
-
-FetchAction_wrongURITitle=Corrupted Configuration
-FetchAction_wrongURIMessage=Remote repositories URIs configuration is corrupted.
-FetchOperationUI_FetchJobName=Fetch from {0}
-
-FetchDestinationPage_PageTitle=Please select a fetch destination
-FetchDestinationPage_CouldNotGetBranchesMessage=Could not obtain tracking branches
-FetchDestinationPage_DestinationLabel=Destination:
-FetchDestinationPage_ForceCheckbox=Update the local repository even if data could be lost
-FetchDestinationPage_PageMessage=The destination is a remote tracking branch in the local repository
-FetchDestinationPage_RepositoryLabel=Local repository:
-FetchDestinationPage_SourceLabel=Source:
-FetchDestinationPage_TrackingBranchNotFoundMessage=Remote tracking branch ''{0}'' not found in local repository
-FetchGerritChangePage_ActivateAdditionalRefsButton=Make FETCH_HEAD visible in &History View
-FetchGerritChangePage_ActivateAdditionalRefsTooltip=The History View is currently configured not to show FETCH_HEAD; if you check this, the History View settings will be changed so that FETCH_HEAD becomes visible
-FetchGerritChangePage_AfterFetchGroup=Action to perform after fetch
-FetchGerritChangePage_BranchNameText=Branch &name
-FetchGerritChangePage_ChangeLabel=&Change:
-FetchGerritChangePage_CheckingOutTaskName=Checking out change
-FetchGerritChangePage_CheckoutRadio=Check&out FETCH_HEAD
-FetchGerritChangePage_ContentAssistDescription=Patch set {0} of change {1}
-FetchGerritChangePage_ContentAssistTooltip=Press {0} to see a filtered list of changes
-FetchGerritChangePage_CreatingBranchTaskName=Creating branch
-FetchGerritChangePage_CreatingTagTaskName=Creating tag
-FetchGerritChangePage_ExistingRefMessage=A branch or tag with name {0} already exists
-FetchGerritChangePage_FetchingTaskName=Fetching change {0}
-FetchGerritChangePage_GeneratedTagMessage=Generated for Gerrit change {0}
-FetchGerritChangePage_GetChangeTaskName=Get change from Gerrit
-FetchGerritChangePage_LocalBranchRadio=Create and checkout a local &branch
-FetchGerritChangePage_MissingChangeMessage=Please provide a change
-FetchGerritChangePage_PageMessage=Please select a Gerrit URI and change to fetch
-FetchGerritChangePage_PageTitle=Fetch a change from Gerrit into repository {0}
-FetchGerritChangePage_ProvideRefNameMessage=Please provide a name for the new branch or tag
-FetchGerritChangePage_SuggestedRefNamePattern=change/{0}/{1}
-FetchGerritChangePage_TagNameText=Tag &name
-FetchGerritChangePage_TagRadio=Create and checkout a &tag
-FetchGerritChangePage_UpdateRadio=U&pdate FETCH_HEAD only
-FetchGerritChangePage_UriLabel=&URI:
-FetchGerritChangeWizard_WizardTitle=Fetch a change from Gerrit
-FetchResultDialog_ConfigureButton=&Configure...
-FetchResultDialog_labelEmptyResult=No ref to fetch from {0} - everything up to date.
-FetchResultDialog_labelNonEmptyResult=Fetched from {0}.
-FetchResultDialog_title=Fetch Results: {0}
-
-FetchResultTable_counterCommits=\ ({0})
-FetchResultTable_statusDetailCouldntLock=couldn't lock local tracking ref for update
-FetchResultTable_statusDetailFastForward=fast-forward
-FetchResultTable_statusDetailIOError=I/O error occurred during local tracking ref update
-FetchResultTable_statusDetailNonFastForward=non-fast-forward
-FetchResultTable_statusIOError=[i/o error]
-FetchResultTable_statusLockFailure=[lock fail]
-FetchResultTable_statusNew=[new]
-FetchResultTable_statusNewBranch=[new branch]
-FetchResultTable_statusNewTag=[new tag]
-FetchResultTable_statusRejected=[rejected]
-FetchResultTable_statusUnexpected=Unexpected update status: {0}
-FetchResultTable_statusUpToDate=[up to date]
-FetchSourcePage_GettingRemoteRefsTaskname=Getting remote refs
-FetchSourcePage_PageMessage=The source is a branch or tag in the remote repository
-FetchSourcePage_PageTitle=Please select a fetch source
-FetchSourcePage_RefNotFoundMessage=Ref ''{0}'' not found in remote repository
-FetchSourcePage_RepositoryLabel=Remote repository:
-FetchSourcePage_SourceLabel=Source:
-FetchWizard_cantSaveMessage=Couldn't save specified specifications in configuration file.
-FetchWizard_cantSaveTitle=Configuration Storage Warning
-FetchWizard_windowTitleDefault=Fetch from Another Repository
-FetchWizard_windowTitleWithSource=Fetch from: {0}
-FileDiffContentProvider_errorGettingDifference=Can''t get file difference of {0}.
-FileRevisionEditorInput_NameAndRevisionTitle={0} {1}
-FileTreeContentProvider_NonWorkspaceResourcesNode=Non-workspace files
-FindToolbar_NextTooltip=Go to next commit matching the search criteria
-FindToolbar_PreviousTooltip=Go to previous commit matching the search criteria
-FormatJob_buildingCommitInfo=Building Commit Info
-
-WindowCachePreferencePage_title=Git Window Cache
-WindowCachePreferencePage_packedGitWindowSize=Window size:
-WindowCachePreferencePage_packedGitLimit=Window cache limit:
-WindowCachePreferencePage_deltaBaseCacheLimit=Delta base cache limit:
-WindowCachePreferencePage_packedGitMMAP=Use virtual memory mapping
-WindowCachePreferencePage_streamFileThreshold=Stream File Threshold:
-
-ProjectsPreferencePage_AutoShareProjects=Auto share projects located in a git repository
-ProjectsPreferencePage_RestoreBranchProjects=Track each branch's imported projects and restore on checkout
-ProjectsPreferencePage_AutoIgnoreDerivedResources=Automatically ignore derived resources by adding them to .gitignore
-
-RefreshPreferencesPage_RefreshOnlyWhenActive=Refresh only when workbench is &active
-RefreshPreferencesPage_RefreshWhenIndexChange=Refresh resources when &index changes
-RefUpdateElement_CommitCountDecoration=({0})
-RefUpdateElement_CommitRangeDecoration=[{0}{1}{2}]
-RefUpdateElement_statusRejectedNonFastForward=[rejected - non-fast-forward]
-RefUpdateElement_UrisDecoration=({0})
-
-CommitDialogPreferencePage_commitMessageHistory=Maximum number of commit messages in history:
-CommitDialogPreferencePage_title=Commit Dialog
-CommitDialogPreferencePage_formatting=Formatting
-CommitDialogPreferencePage_hardWrapMessage=Hard-wrap commit message
-CommitDialogPreferencePage_hardWrapMessageTooltip=Wrap text in commit message editor while typing
-CommitDialogPreferencePage_footers=Footers
-CommitDialogPreferencePage_includeUntrackedFiles=Include selected untracked files
-CommitDialogPreferencePage_includeUntrackedFilesTooltip=Check selected untracked files by default
-CommitDialogPreferencePage_signedOffBy=Insert Signed-off-by
-CommitDialogPreferencePage_signedOffByTooltip=Insert "Signed-off-by:" footer by default
-
-BasicConfigurationDialog_DialogMessage=Git needs your name and e-mail to correctly attribute your commits. Git uses name and e-mail to identify author and committer of a commit.
-BasicConfigurationDialog_DialogTitle=Please identify yourself
-BasicConfigurationDialog_UserEmailLabel=User &e-mail
-BasicConfigurationDialog_UserNameLabel=User &name
-BasicConfigurationDialog_WindowTitle=Identify Yourself
-BranchAction_branchFailed=Branch failed
-BranchAction_cannotCheckout=Cannot checkout now
-BranchAction_checkingOut=Checking out {0} - {1}
-BranchAction_repositoryState=Repository state: {0}
-BranchConfigurationDialog_BranchConfigurationTitle=Git Branch Configuration
-BranchConfigurationDialog_EditBranchConfigMessage=Edit the upstram configuration for branch {0}
-BranchConfigurationDialog_ExceptionGettingRefs=Exception getting Refs
-BranchConfigurationDialog_RebaseLabel=&Rebase
-BranchConfigurationDialog_RemoteLabel=Rem&ote:
-BranchConfigurationDialog_SaveBranchConfigFailed=Could not save branch configuration
-BranchConfigurationDialog_UpstreamBranchLabel=Upstream &Branch:
-BranchOperationUI_DetachedHeadTitle=Detached HEAD
-BranchOperationUI_DetachedHeadMessage=You are in the 'detached HEAD' state. This means that you don't have a local branch checked out.\n\nYou can look around, but it's not recommended to commit changes. The reason is that these commits would not be on any branch and would not be visible after checking out another branch.\n\nIf you want to make changes, create or checkout a local branch first.
-BranchRenameDialog_Message=Please enter a new name for branch {0}
-BranchRenameDialog_NewNameLabel=New Branch &name:
-BranchRenameDialog_RenameExceptionMessage=Could not rename branch
-BranchRenameDialog_Title=Rename Branch
-BranchRenameDialog_WindowTitle=Rename Branch
-BranchRenameDialog_WrongPrefixErrorMessage=Can not rename Ref with name {0}
-BranchPropertySource_RebaseDescriptor=Rebase
-BranchPropertySource_RemoteDescriptor=Remote
-BranchPropertySource_UpstreamBranchDescriptor=Upstream Branch
-BranchPropertySource_UpstreamConfigurationCategory=Upstream Configuration
-BranchPropertySource_ValueNotSet=<Not set>
-BranchResultDialog_buttonCommit=Commit...
-BranchResultDialog_buttonReset=Reset
-BranchResultDialog_buttonStash=Stash...
-BranchResultDialog_CheckoutConflictsMessage=The files shown below have uncommitted changes which would be lost by checking out ''{0}''.\n\nEither commit the changes, stash the changes, or discard the changes by resetting the current branch.
-BranchResultDialog_CheckoutConflictsTitle=Checkout Conflicts
-BranchResultDialog_dontShowAgain=Don't show this confirmation dialog again
-CheckoutDialog_ErrorCouldNotCreateNewRef=Could not create new ref {0}
-CheckoutDialog_ErrorCouldNotDeleteRef=Could not delete ref {0}
-CheckoutDialog_ErrorCouldNotRenameRef=Failed to rename branch {0} -> {1}, status={2}
-
-CheckoutDialog_NewBranch=&New Branch...
-CheckoutDialog_QuestionNewBranchNameMessage=Enter new name of the {0} branch. {1} will be prepended to the name you type
-CheckoutDialog_QuestionNewBranchTitle=New branch
-CheckoutDialog_Rename=&Rename...
-CheckoutDialog_Delete=&Delete
-MergeAction_CannotMerge=Cannot merge now
-MergeAction_HeadIsNoBranch=HEAD is not pointing to a branch
-MergeAction_JobNameMerge=Merging with {0}
-MergeAction_MergeCanceledMessage=The merge operation was canceled
-MergeAction_MergeCanceledTitle=Merge Canceled
-MergeAction_MergeResultTitle=Merge Result
-MergeAction_WrongRepositoryState=The current repository state ''{0}'' does not allow merging
-MergeModeDialog_DialogTitle=Select a Merge Mode
-MergeModeDialog_DontAskAgainLabel=&Don't ask again
-MergeModeDialog_MergeMode_1_Label=Use the &workspace version of conflicting files (pre-merged by Git)
-MergeModeDialog_MergeMode_2_Label=Use &HEAD (the last local version) of conflicting files
-MergeResultDialog_couldNotFindCommit=Could not find commit: {0}
-MergeResultDialog_description=Description
-MergeResultDialog_id=Commit Id
-MergeResultDialog_failed=Failed Paths
-MergeResultDialog_mergeInput=Merge input
-MergeResultDialog_mergeResult=Merge result
-MergeResultDialog_newHead=New HEAD
-MergeResultDialog_nMore=... {0} more
-MergeResultDialog_result=Result
-MergeTargetSelectionDialog_ButtonMerge=&Merge
-MergeTargetSelectionDialog_SelectRef=Select a branch or tag to merge into the currently checked out branch
-MergeTargetSelectionDialog_SelectRefWithBranch=Select a branch or tag to merge into the ''{0}'' branch
-MergeTargetSelectionDialog_TitleMerge=Merge Branch
-MergeTargetSelectionDialog_TitleMergeWithBranch=Merge ''{0}''
-MergeTargetSelectionDialog_FastForwardGroup=Fast forward options
-MergeTargetSelectionDialog_FastForwardButton=If a fast-forward, &only update the branch pointer
-MergeTargetSelectionDialog_NoFastForwardButton=If a fast-forward, create a &merge commit
-MergeTargetSelectionDialog_OnlyFastForwardButton=If &not a fast-forward, fail
-MergeTargetSelectionDialog_MergeTypeGroup=Merge options
-MergeTargetSelectionDialog_MergeTypeCommitButton=&Commit (commit the result)
-MergeTargetSelectionDialog_MergeTypeSquashButton=&Squash (do not make a commit)
-
-DecoratorPreferencesPage_addVariablesTitle=Add Variables
-DecoratorPreferencesPage_addVariablesAction=Add &Variables...
-DecoratorPreferencesPage_addVariablesAction2=Add Va&riables...
-DecoratorPreferencesPage_addVariablesAction3=Add Var&iables...
-DecoratorPreferencesPage_recomputeAncestorDecorations=Re-decorate &ancestors when decorating changed resources
-DecoratorPreferencesPage_recomputeAncestorDecorationsTooltip=Enabling this option will cause the ancestor-tree of any updated resources to also be re-decorated (minor performance impact).
-DecoratorPreferencesPage_description=Shows Git specific information on resources in projects under version control.
-DecoratorPreferencesPage_preview=Preview:
-DecoratorPreferencesPage_fileFormatLabel=&Files:
-DecoratorPreferencesPage_folderFormatLabel=F&olders:
-DecoratorPreferencesPage_projectFormatLabel=&Projects:
-DecoratorPreferencesPage_labelDecorationsLink=See <a>''{0}''</a> to enable or disable Git decorations.
-DecoratorPreferencesPage_colorsAndFontsLink=See <a>''{0}''</a> to configure the font and color decorations.
-DecoratorPreferencesPage_generalTabFolder=&General
-DecoratorPreferencesPage_bindingResourceName=Name of the resource being decorated
-DecoratorPreferencesPage_bindingBranchName=Current branch of the repository
-DecoratorPreferencesPage_bindingBranchStatus=Branch status (compared to remote-tracking)
-DecoratorPreferencesPage_bindingDirtyFlag=Flag indicating whether or not the resource is dirty
-DecoratorPreferencesPage_bindingStagedFlag=Flag indicating whether or not the resource is staged
-DecoratorPreferencesPage_selectVariablesToAdd=Select the &variables to add to the decoration format:
-DecoratorPreferencesPage_textLabel=T&ext Decorations
-DecoratorPreferencesPage_iconLabel=&Icon Decorations
-DecoratorPreferencesPage_iconsShowTracked=Tracked resources
-DecoratorPreferencesPage_iconsShowUntracked=Untracked resources
-DecoratorPreferencesPage_iconsShowStaged=Staged resources
-DecoratorPreferencesPage_iconsShowConflicts=Conflicting resources
-DecoratorPreferencesPage_iconsShowAssumeValid=Assumed unchanged resources
-DecoratorPreferencesPage_changeSetLabelFormat=Commits:
-DecoratorPreferencesPage_otherDecorations=Other
-DecoratorPreferencesPage_dateFormat=Date format:
-DecoratorPreferencesPage_dateFormatPreview=Date preview:
-DecoratorPreferencesPage_wrongDateFormat=#Incorrect date format#
-DecoratorPreferencesPage_bindingChangeSetAuthor=Commit author name;
-DecoratorPreferencesPage_bindingChangeSetCommitter=Commit committer name;
-DecoratorPreferencesPage_bindingChangeSetDate=Commit creation date (see date format setting);
-DecoratorPreferencesPage_bindingChangeSetShortMessage=First line of commit message text;
-
-Decorator_exceptionMessage=Errors occurred while applying Git decorations to resources.
-DeleteBranchCommand_CannotDeleteCheckedOutBranch=Can not delete the currently checked out branch
-DeleteBranchCommand_DeletingBranchesProgress=Deleting branches
-DeleteBranchDialog_DialogMessage=Select a branch to delete
-DeleteBranchDialog_DialogTitle=Delete a branch
-DeleteBranchDialog_WindowTitle=Delete branch
-DeleteBranchOnCommitHandler_SelectBranchDialogMessage=Please select the branches you want to delete
-DeleteBranchOnCommitHandler_SelectBranchDialogTitle=Delete Branches
-DeleteRepositoryConfirmDialog_DeleteRepositoryMessage=This will permanently delete repository ''{0}''.
-DeleteRepositoryConfirmDialog_DeleteRepositoryTitle=Delete Repository {0}
-DeleteRepositoryConfirmDialog_DeleteRepositoryWindowTitle=Delete Repository
-DeleteRepositoryConfirmDialog_DeleteWorkingDirectoryCheckbox=Also delete repository content in &working directory {0}
-DeleteRepositoryConfirmDialog_DeleteProjectsCheckbox=Remove the {0} projects that belong to the removed repositories from the workspace
-DeleteTagCommand_messageConfirmMultipleTag=Are you sure you want to delete these {0} tags?
-DeleteTagCommand_messageConfirmSingleTag=Are you sure you want to delete tag ''{0}''?
-DeleteTagCommand_taskName=Deleting tag
-DeleteTagCommand_titleConfirm=Confirm Tag Deletion
-DeleteResourcesOperationUI_confirmActionTitle=Delete Resources
-DeleteResourcesOperationUI_confirmActionMessage=Are you sure you want to delete the selected files from the file system?
-DeleteResourcesOperationUI_deleteFailed=Deleting resources failed
-
-IgnoreActionHandler_addToGitignore=Add to .gitignore
-
-RepositoriesView_BranchDeletionFailureMessage=Branch deletion failed
-RepositoriesView_Branches_Nodetext=Branches
-RepositoriesView_ClipboardContentNoGitRepoMessage=Path {0} does not appear to be a Git repository location
-RepositoriesView_ClipboardContentNotDirectoryOrURIMessage=Clipboard content is neither a directory path nor a valid git URI
-RepositoriesView_ConfirmDeleteRemoteHeader=Confirm Remote Configuration Deletion
-RepositoriesView_ConfirmDeleteRemoteMessage=Are you sure you want to remove remote configuration ''{0}''?
-RepositoriesView_ConfirmProjectDeletion_Question=There are {0} projects that belong to the removed repositories, do you want to remove them from the workspace?
-RepositoriesView_ConfirmProjectDeletion_WindowTitle=Confirm Project Deletion
-RepositoriesView_DeleteRepoDeterminProjectsMessage=Determining projects that must be deleted
-RepositoriesView_Error_WindowTitle=Error
-RepositoriesView_ErrorHeader=Error
-RepositoriesView_ExceptionLookingUpRepoMessage=An exception occurred while looking up the repository path ''{0}''; it will be removed from the Git Repositories view
-RepositoriesView_linkAdd=Add an existing local Git repository
-RepositoriesView_linkClone=Clone a Git repository
-RepositoriesView_linkCreate=Create a new local Git repository
-RepositoriesView_messsageEmpty=Select one of the following to add a repository to this view:
-RepositoriesView_NothingToPasteMessage=Clipboard contains no data to paste
-RepositoriesView_PasteRepoAlreadyThere=Repository at location {0} is already in the list
-RepositoriesView_RemotesNodeText=Remotes
-RepositoriesView_WorkingDir_treenode=Working Directory
-RepositoriesViewContentProvider_ExceptionNodeText=Exception encountered while fetching children
-RepositoriesViewLabelProvider_LocalNodetext=Local
-RepositoriesViewLabelProvider_RemoteTrackingNodetext=Remote Tracking
-RepositoriesViewLabelProvider_StashNodeText=Stashed Commits
-RepositoriesViewLabelProvider_SubmodulesNodeText=Submodules
-RepositoriesViewLabelProvider_SymbolicRefNodeText=References
-RepositoriesViewLabelProvider_TagsNodeText=Tags
-
-DialogsPreferencePage_DetachedHeadCombo=D&etached HEAD warning
-DialogsPreferencePage_DontShowDialog=Do not prompt
-DialogsPreferencePage_HideConfirmationGroupHeader=Show confirmation dialogs
-DialogsPreferencePage_HideWarningGroupHeader=Log warnings
-DialogsPreferencePage_HomeDirWarning=&Home directory warning (Windows only)
-DialogsPreferencePage_GitPrefixWarning=&Git prefix warning (Windows typically)
-DialogsPreferencePage_RebaseCheckbox=&Rebase confirmation
-DialogsPreferencePage_ShowDialog=Prompt
-DialogsPreferencePage_ShowInitialConfigCheckbox=&Initial configuration
-DialogsPreferencePage_ShowCloneFailedDialog=Clone failed error
-DiffEditorPage_TaskGeneratingDiff=Generating diff
-DiffEditorPage_TaskUpdatingViewer=Updating diff viewer
-DiffEditorPage_Title=Diff
-DiscardChangesAction_confirmActionTitle=Discard Local Changes
-DiscardChangesAction_confirmActionMessage=This will discard all local changes for the selected resources. Untracked files will be ignored. Are you sure you want to do this?
-DiscardChangesAction_discardChanges=Discard Changes
-Disconnect_disconnect=Disconnect
-
-GitCompareEditorInput_CompareResourcesTaskName=Comparing Resources
-GitCompareEditorInput_EditorTitle=Repository ''{0}'': Comparing ''{1}'' with ''{2}''
-GitCompareEditorInput_EditorTitleMultipleResources=Multiple Resources: Comparing  ''{0}'' with ''{1}''
-GitCompareEditorInput_EditorTitleSingleResource=''{0}'': Comparing ''{1}'' with ''{2}''
-GitCompareEditorInput_ResourcesInDifferentReposMessagge=Resources belong to different repositories
-GitCompareFileRevisionEditorInput_CompareInputTitle={0}
-GitCompareFileRevisionEditorInput_CompareTooltip=Compare {0} {1} and {2}
-GitCompareFileRevisionEditorInput_CurrentRevision=Current Revision
-GitCompareFileRevisionEditorInput_CurrentTitle=Current
-GitCompareFileRevisionEditorInput_contentIdentifier=Problem getting content identifier
-GitCompareFileRevisionEditorInput_LocalHistoryLabel=Local history: {0} {1}
-GitCompareFileRevisionEditorInput_LocalLabel=Local: {0}
-GitCompareFileRevisionEditorInput_LocalRevision=Local Revision
-GitCompareFileRevisionEditorInput_RevisionLabel={0} {1} ({2})
-GitCompareFileRevisionEditorInput_LocalVersion={0} (local version)
-GitCompareFileRevisionEditorInput_StagedVersion={0} (staged version)
-GitCreateGeneralProjectPage_DirLabel=Directory
-GitCreateGeneralProjectPage_DirNotExistMessage=Directory {0} does not exist
-GitCreateGeneralProjectPage_EnterProjectNameMessage=Please provide a project name
-GitCreateGeneralProjectPage_FileExistsInDirMessage=A {0} file already exists in directory {1}
-GitCreateGeneralProjectPage_FileNotDirMessage=File {0} is not a directory
-GitCreateGeneralProjectPage_PorjectAlreadyExistsMessage=Project {0} already exists
-GitCreateGeneralProjectPage_ProjectNameLabel=Project name
-GitCreatePatchAction_cannotCreatePatch=Cannot create patch
-GitCreatePatchAction_workingTreeClean=There are no changes in the workspace for the current selection
-GitCreatePatchWizard_Browse=B&rowse...
-GitCreatePatchWizard_Clipboard=&Clipboard
-GitCreatePatchWizard_ContextMustBePositiveInt=Context must be a valid number of lines ( >= 0 )
-GitCreatePatchWizard_CreatePatchTitle=Create Patch
-GitCreatePatchWizard_File=Fil&e
-GitCreatePatchWizard_Format=Format
-GitCreatePatchWizard_InternalError=An internal error occurred.
-GitCreatePatchWizard_SelectLocationDescription=Select the location for the patch.
-GitCreatePatchWizard_SelectLocationTitle=Create a Patch
-GitCreatePatchWizard_SelectOptionsDescription=Select options for patch creation
-GitCreatePatchWizard_SelectOptionsTitle=Select Options
-GitCreatePatchWizard_FilesystemError=Please select a location in the file system by browsing.
-GitCreatePatchWizard_FilesystemInvalidError=Please enter a valid location.
-GitCreatePatchWizard_FilesystemDirectoryError=Please enter a file name.
-GitCreatePatchWizard_FilesystemDirectoryNotExistsError=The specified directory does not exist.
-GitCreatePatchWizard_LinesOfContext=Lines of &context:
-GitCreatePatchWizard_ReadOnlyTitle=Read-only file
-GitCreatePatchWizard_ReadOnlyMsg=The specified file is read-only and cannot be overwritten.
-GitCreatePatchWizard_OverwriteTitle=Confirm Overwrite
-GitCreatePatchWizard_OverwriteMsg=A file with that name already exists. Overwrite?
-GitCreatePatchWizard_Workspace=&Workspace
-GitCreatePatchWizard_WorkspacePatchDialogTitle=Set a Patch Location
-GitCreatePatchWizard_WorkspacePatchDialogDescription=Select a folder in the workspace and enter a name for the patch.
-GitCreatePatchWizard_WorkspacePatchDialogEnterFileName=Please enter a file name.
-GitCreatePatchWizard_WorkspacePatchDialogEnterValidLocation=Please enter a valid location.
-GitCreatePatchWizard_WorkspacePatchDialogFileName=Fi&le name:
-GitCreatePatchWizard_WorkspacePatchDialogSavePatch=Save Patch
-GitCreatePatchWizard_WorkspacePatchEnterValidFileName=Please enter a valid filename.
-GitCreatePatchWizard_WorkspacePatchFolderExists=The specified path points to an existing folder.
-GitCreatePatchWizard_WorkspacePatchProjectClosed=The specified path points to a closed project.
-GitCreatePatchWizard_WorkspacePatchSelectByBrowsing=Please select a location in the workspace by browsing.
-GitCreateProjectViaWizardWizard_AbortedMessage=Action was aborted
-GitCreateProjectViaWizardWizard_WizardTitle=Import Projects from Git Repository {0}
-GitImportWithDirectoriesPage_PageMessage=Depending on the wizard, you may select a directory to determine the wizard's scope
-GitImportWithDirectoriesPage_PageTitle=Select a wizard to use for importing projects
-GitImportWithDirectoriesPage_SelectFolderMessage=Please select a folder
-GitImportWizard_errorParsingURI=The URI of the repository to be cloned can't be parsed
-GitImportWizard_noRepositoryInfo=The repository info could not be created
-GitImportWizard_WizardTitle=Import Projects from Git
-GitScopeOperation_couldNotDetermineState=Could not determine state of changed files
-GitScopeOperation_GitScopeManager=Git Scope Manager
-GitSelectRepositoryPage_AddButton=&Add...
-GitSelectRepositoryPage_AddTooltip=Add a Git repository from the local file system
-GitSelectRepositoryPage_CloneButton=&Clone...
-GitSelectRepositoryPage_CloneTooltip=Clone a Git repository and add it to the list
-GitSelectRepositoryPage_NoRepoFoundMessage=No repositories found, please clone or add a repository
-GitSelectRepositoryPage_PageMessage=You can also clone a repository or add local repositories to the list
-GitSelectRepositoryPage_PageTitle=Select a Git Repository
-GitSelectRepositoryPage_PleaseSelectMessage=Please select a repository from the list
-GitSelectWizardPage_ImportAsGeneralButton=Import as &general project
-GitSelectWizardPage_ImportExistingButton=Import &existing projects
-GitSelectWizardPage_ProjectCreationHeader=Wizard for project import
-GitSelectWizardPage_UseNewProjectsWizardButton=Use the New &Project wizard
-ConfigurationChecker_gitPrefixWarningMessage=\
-Warning: EGit couldn't detect the installation path "gitPrefix" of native Git. Hence EGit can't respect system level\n\
-Git settings which might be configured in ${gitPrefix}/etc/gitconfig under the native Git installation directory.\n\
-The most important of these settings is core.autocrlf. Git for Windows by default sets this parameter to true in\n\
-this system level configuration. The Git installation location can be configured on the\n\
-Team > Git > Configuration preference page's 'System Settings' tab.\n\
-This warning can be switched off on the Team > Git > Confirmations and Warnings preference page.
-ConfigurationChecker_checkConfiguration=Check Configuration
-ConfigurationChecker_homeNotSet=\
-Warning: The environment variable HOME is not set. The following directory will be used to store the Git\n\
-user global configuration and to define the default location to store repositories: ''{0}''. If this is\n\
-not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and\n\
-EGit might behave differently since they see different configuration options.\n\
-This warning can be switched off on the Team > Git > Confirmations and Warnings preference page.
-ConfigurationEditorComponent_BrowseForPrefix=&Browse...
-ConfigurationEditorComponent_CannotChangeGitPrefixError=Cannot change Git prefix
-ConfigurationEditorComponent_ConfigLocationLabel=&Location:
-ConfigurationEditorComponent_EmptyStringNotAllowed=Empty string is not allowed
-ConfigurationEditorComponent_KeyColumnHeader=Key
-ConfigurationEditorComponent_AddButton=Add &Entry...
-ConfigurationEditorComponent_NoConfigLocationKnown=Unknown
-ConfigurationEditorComponent_NoEntrySelectedMessage=No configuration entry selected
-ConfigurationEditorComponent_NoSectionSubsectionMessage=Neither a section nor subsection
-ConfigurationEditorComponent_OpenEditorButton=&Open
-ConfigurationEditorComponent_OpenEditorTooltip=Open a text editor for this configuration
-ConfigurationEditorComponent_ReadOnlyLocationFormat={0} (non-writable)
-ConfigurationEditorComponent_RemoveButton=&Remove
-ConfigurationEditorComponent_RemoveTooltip=Removes the selected entry or all entries in the selected section or subsection
-ConfigurationEditorComponent_GitPrefixSelectionErrorMessage=This directory does not look like a Git installation directory.\nYou do not need this setting unless you have a system wide configuration file.
-ConfigurationEditorComponent_GitPrefixSelectionErrorTitle=Git Prefix Selection
-ConfigurationEditorComponent_RemoveSectionMessage=All entries in section ''{0}'' will be removed.\n\nDo you want to continue?
-ConfigurationEditorComponent_RemoveSectionTitle=Remove Section
-ConfigurationEditorComponent_RemoveSubsectionMessage=All entries in subsection ''{0}'' will be removed.\n\nDo you want to continue?
-ConfigurationEditorComponent_RemoveSubsectionTitle=Remove Subsection
-ConfigurationEditorComponent_SelectGitInstallation=Select the Git Installation
-ConfigurationEditorComponent_ValueColumnHeader=Value
-ConfigurationEditorComponent_WrongNumberOfTokensMessage=Wrong number of tokens
-ConfigureGerritWizard_title=Gerrit Configuration
-ContinueRebaseCommand_CancelDialogMessage=The abort operation was canceled
-ContinueRebaseCommand_JobName=Continuing Rebase
-MixedResetToRevisionAction_mixedReset=Mixed Reset
-
-GlobalConfigurationPreferencePage_systemSettingTabTitle=&System Settings
-GlobalConfigurationPreferencePage_userSettingTabTitle=&User Settings
-GlobalConfigurationPreferencePage_repositorySettingTabTitle=Repository Sett&ings
-GlobalConfigurationPreferencePage_repositorySettingRepositoryLabel=Reposi&tory:
-GlobalConfigurationPreferencePage_repositorySettingNoRepositories=No repositories configured
-
-UIIcons_errorDeterminingIconBase=Can't determine icon base.
-UIIcons_errorLoadingPluginImage=Can't load plugin image.
-UIUtils_CollapseAll=Collapse All
-UIUtils_ExpandAll=Expand All
-UIUtils_PressShortcutMessage=Press {0} or begin typing to see a filtered list of previously used values (use "*" as wildcard)
-UIUtils_StartTypingForPreviousValuesMessage=Start typing to see a filtered list of previously used values (use "*" as wildcard)
-UIUtils_ShowInMenuLabel=Sho&w In
-UnmergedBranchDialog_Message=Not all commits of these branches have been merged into the currently checked out branch.\n\nDo you still want to delete these branches?
-UnmergedBranchDialog_Title=Confirm Branch Deletion
-Untrack_untrack=Untrack
-
-TagAction_cannotCheckout=Cannot checkout now
-TagAction_cannotGetBranchName=Cannot get actual branch name
-TagAction_repositoryState=Cannot checkout repository because it is in state: {0}
-TagAction_errorWhileGettingRevCommits=An error occurred while getting list of commits.
-TagAction_unableToResolveHeadObjectId=Unable to resolve object id associated with current HEAD.
-TagAction_creating=Creating {0} tag.
-TagAction_taggingFailed=Tagging failed
-
-CreateTagDialog_tagName=Tag &name*:
-CreateTagDialog_tagMessage=Tag &message*:
-CreateTagDialog_questionNewTagTitle=Create New Tag on Branch ''{0}''
-CreateTagDialog_overwriteTag=Force &replace existing tag
-CreateTagDialog_overwriteTagToolTip=Select this option if you want to change message or commit associated with already existing tag.
-CreateTagDialog_existingTags=&Existing tags:
-CreateTagDialog_advanced=&Advanced
-CreateTagDialog_advancedToolTip=In the advanced section you may choose the commit to be tagged.
-CreateTagDialog_advancedMessage=Choose commit that should be associated with this tag.
-CreateTagDialog_tagNameToolTip=Start typing tag name to filter list of existing tags.
-CreateTagDialog_clearButton=C&lear
-CreateTagDialog_clearButtonTooltip=Clear all dialog fields.
-CreateTagDialog_CreateTagOnCommitTitle=Create a New Tag on Commit {0}
-CreateTagDialog_ExceptionRetrievingTagsMessage=Exception while retrieving existing tags
-CreateTagDialog_GetTagJobName=Get existing tags for the Create Tag Dialog
-CreateTagDialog_LightweightTagMessage=This is a lightweight tag which can not be edited
-CreateTagDialog_LoadingMessageText=Loading...
-CreateTagDialog_Message=Create a new tag or replace an existing one
-CreateTagDialog_NewTag=Create New Tag
-
-CommitCombo_showSuggestedCommits=Start typing SHA-1 of existing commit or part of first line in commit message to see suggested commits.
-CommitCommand_committingNotPossible=Committing not possible
-CommitCommand_noProjectsImported=No projects are imported into the workspace for this repository. For the time being committing is currently only possible for workspace resources.
-
-CommitAction_commit=Commit...
-CommitAction_ErrorReadingMergeMsg=Error reading from file .git/MERGE_MSG
-CommitAction_MergeHeadErrorMessage=The file .git/MERGE_MSG was not found although being in state "merged".
-CommitAction_MergeHeadErrorTitle=Inconsistent Merge State
-CommitActionHandler_calculatingChanges=Calculating changes in selected repositories
-CommitActionHandler_errorBuildingScope=Error occurred while building scope for committing changes
-CommitActionHandler_lookingForChanges=Looking for uncommitted changes
-CommitActionHandler_repository=Repository: {0}
-CommitEditor_couldNotShowRepository=Could not show repository
-CommitEditor_showGitRepo=Show Git repository
-CommitEditor_TitleHeader=Commit {0}
-CommitEditorInput_Name={0} [{1}]
-CommitEditorInput_ToolTip=Commit {0} in repository {1}
-CommitEditorPage_JobName=Loading commit ''{0}''
-CommitEditorPage_SectionBranchesEmpty=Branches
-CommitEditorPage_LabelAuthor={0} <{1}> on {2}
-CommitEditorPage_LabelCommitter={0} <{1}> on {2}
-CommitEditorPage_LabelParent=Parent:
-CommitEditorPage_LabelTags=Tags:
-CommitEditorPage_SectionBranches=Branches ({0})
-CommitEditorPage_SectionFiles=Files ({0})
-CommitEditorPage_SectionFilesEmpty=Files
-CommitEditorPage_SectionMessage=Message
-CommitEditorPage_Title=Commit
-CommitEditorPage_TooltipAuthor=Author
-CommitEditorPage_TooltipCommitter=Committer
-CommitEditorPage_TooltipSignedOffByAuthor=Signed off by author
-CommitEditorPage_TooltipSignedOffByCommitter=Signed off by committer
-
-Header_contextMenu_copy=&Copy
-Header_contextMenu_copy_SHA1=Copy &SHA-1
-Header_copy_SHA1_error_title= Problem Copying SHA-1 to Clipboard
-Header_copy_SHA1_error_message= There was a problem when accessing the system clipboard. Retry?
-
-MergeHandler_SelectBranchMessage=There is more than one ref for this commit. Please select the ref you want to merge.
-MergeHandler_SelectBranchTitle=Select a Ref for Merge
-MultiPullResultDialog_DetailsButton=&Details
-MultiPullResultDialog_FetchStatusColumnHeader=Fetch Status
-MultiPullResultDialog_MergeResultMessage=Merge result: {0}
-MultiPullResultDialog_NothingFetchedStatus=Nothing fetched
-MultiPullResultDialog_NothingUpdatedStatus=Nothing updated
-MultiPullResultDialog_OkStatus=OK
-MultiPullResultDialog_FailedStatus=Failed
-MultiPullResultDialog_OverallStatusColumnHeader=Overall Status
-MultiPullResultDialog_RebaseResultMessage=Rebase result: {0}
-MultiPullResultDialog_RepositoryColumnHeader=Repository
-MultiPullResultDialog_UnknownStatus=Unknown
-MultiPullResultDialog_UpdatedMessage={0} refs were updated
-MultiPullResultDialog_UpdatedOneMessage=1 ref was updated
-MultiPullResultDialog_UpdateStatusColumnHeader=Update Status
-MultiPullResultDialog_WindowTitle=Pull Result for Multiple Repositories
-
-CommitFileDiffViewer_CanNotOpenCompareEditorTitle=Can not Open Compare Editor
-CommitFileDiffViewer_CompareMenuLabel=Compare with &Version in Ancestor
-CommitFileDiffViewer_CompareWorkingDirectoryMenuLabel=Compare with &Workspace
-CommitFileDiffViewer_FileDoesNotExist=File {0} does not exist in the workspace
-CommitFileDiffViewer_MergeCommitMultiAncestorMessage=This is a merge commit with more than one ancestor
-CommitFileDiffViewer_notContainedInCommit=File {0} is not contained in commit {1}
-CommitFileDiffViewer_OpenInEditorMenuLabel=Open &This Version
-CommitFileDiffViewer_OpenWorkingTreeVersionInEditorMenuLabel=&Open Workspace Version
-CommitFileDiffViewer_ShowAnnotationsMenuLabel=Show Annotations
-CommitGraphTable_CommitId=Id
-CommitGraphTable_Committer=Committer
-CommitGraphTable_committerDataColumn=Committed Date
-CommitGraphTable_CompareWithEachOtherInTreeMenuLabel=Compare with Each Other in &Tree
-CommitGraphTable_DeleteBranchAction=&Delete Branch
-CommitGraphTable_messageColumn=Message
-CommitGraphTable_OpenCommitLabel=Open in Commit &Viewer
-CommitGraphTable_RenameBranchMenuLabel=Re&name Branch...
-CommitGraphTable_UnableToCreatePatch=Unable to create patch for {0}
-CommitGraphTable_UnableToWritePatch=Unable to write temporary patch for {0}
-CommitHelper_couldNotFindMergeMsg=Inconsistent merge state: could not find file {0} in .git folder. This file contains the commit message for a merge commit.
-CommitResultLabelProvider_SectionAuthor=\ ({0} on {1})
-CommitResultLabelProvider_SectionMessage={0}: {1}
-CommitResultLabelProvider_SectionRepository=\ [{0}]
-CommitSearchPage_Author=&Author
-CommitSearchPage_CaseSensitive=&Case sensitive
-CommitSearchPage_CheckAll=Check all
-CommitSearchPage_CommitId=Comm&it id
-CommitSearchPage_Committer=C&ommitter
-CommitSearchPage_ContainingText=Containing &text:
-CommitSearchPage_ContainingTextHint=(* = any string, ? = any character, \\ = escape for literals: * ? \\)
-CommitSearchPage_Message=&Message
-CommitSearchPage_ParentIds=&Parent id(s)
-CommitSearchPage_RegularExpression=Regular e&xpression
-CommitSearchPage_Repositories=Repositories ({0}/{1})
-CommitSearchPage_Scope=Scope
-CommitSearchPage_SearchAllBranches=Search all &branches of selected repositories
-CommitSearchPage_TreeId=T&ree id
-CommitSearchPage_UncheckAll=Uncheck all
-CommitSearchQuery_Label=Git Commit Search
-CommitSearchQuery_TaskSearchCommits=Searching commits in {0}
-CommitSearchResult_LabelPlural=''{0}'' - {1} commit matches
-CommitSearchResult_LabelSingle=''{0}'' - 1 commit match
-CommitSelectDialog_AuthoColumn=Author
-CommitSelectDialog_DateColumn=Date
-CommitSelectDialog_IdColumn=Id
-CommitSelectDialog_Message=Please select a Commit
-CommitSelectDialog_MessageColumn=Message
-CommitSelectDialog_Title=Commit Selection
-CommitSelectDialog_WindowTitle=Commit Selection
-CommitSelectionDialog_BuildingCommitListMessage=Building commit list
-CommitSelectionDialog_DialogMessage=Please select a commit from the list
-CommitSelectionDialog_DialogTitle={0} commits in repository {1}
-CommitSelectionDialog_FoundCommitsMessage=Found {0} commits
-CommitSelectionDialog_IncompleteListMessage=The commit list may be incomplete
-CommitSelectionDialog_LinkSearch=<a>Search repositories for commits...</a>
-CommitSelectionDialog_Message=&Enter branch, tag, or commit SHA-1:
-CommitSelectionDialog_SectionMessage=: {0}
-CommitSelectionDialog_SectionRepo=\ [{0}]
-CommitSelectionDialog_TaskSearching=Searching commits
-CommitSelectionDialog_Title=Open Git Commit
-CommitSelectionDialog_WindowTitle=Select a Commit
-CommitUI_commitFailed=Commit failed
-CommitUI_pushFailedTitle=Push failed
-CommitUI_pushFailedMessage=Could not push {0} to {1}: {2}
-
-GitSynchronizeWizard_synchronize=Synchronize
-GitChangeSetModelProviderLabel=Git Commits
-
-GitBranchSynchronizeWizardPage_title=Synchronize Git
-GitBranchSynchronizeWizardPage_description=Select destination for repositories to be synchronized.
-GitBranchSynchronizeWizardPage_repositories=Repositories
-GitBranchSynchronizeWizardPage_destination=Destination
-GitBranchSynchronizeWizardPage_includeUncommitedChanges=Include local &uncommitted changes in comparison
-GitBranchSynchronizeWizardPage_fetchChangesFromRemote=Fetch changes from remote
-GitBranchSynchronizeWizardPage_selectAll=Select All
-GitBranchSynchronizeWizardPage_deselectAll=Deselect All
-
-GitTraceConfigurationDialog_ApplyButton=&Apply
-GitTraceConfigurationDialog_DefaultButton=&Default
-GitTraceConfigurationDialog_DialogTitle=Maintain the Git Trace Configuration
-GitTraceConfigurationDialog_LocationHeader=Location
-GitTraceConfigurationDialog_MainSwitchNodeText=Main switch for plug-in {0}
-GitTraceConfigurationDialog_OpenInEditorButton=Open in &Editor
-GitTraceConfigurationDialog_PlatformSwitchCheckbox=Enable &Platform Trace
-GitTraceConfigurationDialog_PlatformTraceDisabledMessage=Platform Trace is currently disabled, please enable it in order to edit the trace configuration
-GitTraceConfigurationDialog_ShellTitle=Git Trace Configuration
-GitTraceConfigurationDialog_TraceFileLocationLabel=Trace File &Location:
-
-ImportProjectsWrongSelection = Wrong selection
-ImportProjectsSelectionInRepositoryRequired = A folder selection in the Repository View is required
-
-LocalFileRevision_CurrentVersion=*({0})
-LocalFileRevision_currentVersionTag=<current version>
-LocalNonWorkspaceTypedElement_errorWritingContents=Error writing contents for local non-workspace element.
-LoginDialog_changeCredentials=Change stored credentials
-LoginDialog_login=Login
-LoginDialog_password=Password
-LoginDialog_repository=Repository
-LoginDialog_storeInSecureStore=Store in Secure Store
-LoginDialog_user=User
-LoginService_readingCredentialsFailed=Reading credentials failed
-LoginService_storingCredentialsFailed=Storing credentials failed
-NewRemoteDialog_ConfigurationMessage=You need to configure the new remote for either fetch or push; you can add configuration for the other direction later
-NewRemoteDialog_DialogTitle=Please enter a name for the new remote
-NewRemoteDialog_FetchRadio=Configure &fetch
-NewRemoteDialog_NameLabel=Remote &name:
-NewRemoteDialog_PushRadio=Configure &push
-NewRemoteDialog_RemoteAlreadyExistsMessage=Remote {0} already exists
-NewRemoteDialog_WindowTitle=New Remote
-NewRepositoryWizard_WizardTitle=Create a Git Repository
-NonDeletedFilesDialog_NonDeletedFilesMessage=The files below could not be deleted, \nperhaps because of some temporary file locks\nor because a directory represents a submodule
-NonDeletedFilesDialog_NonDeletedFilesTitle=Not deleted Files
-NonDeletedFilesDialog_RetryDeleteButton=&Retry delete
-NonDeletedFilesTree_FileSystemPathsButton=Show file &system paths
-NonDeletedFilesTree_RepoRelativePathsButton=Show &repository relative paths
-NonDeletedFilesTree_RepositoryLabel=Repository:
-NonDeletedFilesTree_ResourcePathsButton=Show resource &paths
-NoteDetailsPage_ContentSection=Note Content
-NotesBlock_NotesSection=Notes ({0})
-NotesEditorPage_Title=Notes
-
-RemoteConnectionPreferencePage_TimeoutLabel=&Remote connection timeout (seconds):
-RemoteConnectionPreferencePage_ZeroValueTooltip=0 is equivalent to no timeout
-RemoveCommand_ConfirmDeleteBareRepositoryMessage=This will permanently delete repository ''{0}''.\n\nDo you want to continue?
-RemoveCommand_ConfirmDeleteBareRepositoryTitle=Delete Bare Repository
-RenameBranchDialog_DialogMessage=Select a branch to rename
-RenameBranchDialog_DialogTitle=Rename a Branch
-RenameBranchDialog_NewNameInputDialogPrompt=Enter new name of the {0} branch. {1} will be prepended to the name you type
-RenameBranchDialog_RenameBranchDialogNewNameInputWindowTitle=New Branch Name
-RenameBranchDialog_RenameButtonLabel=&Rename
-RenameBranchDialog_RenameErrorMessage=Failed to rename branch {0} -> {1}, status={2}
-RenameBranchDialog_WindowTitle=Branch Rename
-RenameBranchOnCommitHandler_SelectBranchDialogMessage=Please select the branch you want to rename
-RenameBranchOnCommitHandler_SelectBranchDialogTitle=Rename Branch
-RevertFailureDialog_Message=Reverting commit ''{0}'' did not successfully complete.\n\nThe following files could not be reverted:
-RevertFailureDialog_MessageNoFiles=Reverting commit ''{0}'' did not successfully complete.
-RevertFailureDialog_ReasonChangesInIndex=Local Changes in Index
-RevertFailureDialog_ReasonChangesInWorkingDirectory=Local Changes in Working Directory
-RevertFailureDialog_ReasonDeleteFailure=Unable to Delete
-RevertFailureDialog_Title=Revert Failed
-RevertHandler_AlreadyRevertedMessage=The change has already been reverted
-RevertHandler_JobName=Reverting Commit {0}
-RevertHandler_NoRevertTitle=No revert performed
-RevertOperation_Failed=The revert failed
-RevertOperation_InternalError=An internal error occurred
-
-SelectUriWiazrd_Title=Select a URI
-SimpleConfigurePushDialog_UseUriForPushUriMessage=No Push URIs, will use URI {0}
-SimpleConfigurePushDialog_WindowTitle=Configure Push
-SimpleConfigurePushDialog_AddPushUriButton=&Add...
-SimpleConfigurePushDialog_AddRefSpecButton=A&dd...
-SimpleConfigurePushDialog_AdvancedButton=&Advanced
-SimpleConfigurePushDialog_BranchLabel=Branch:
-SimpleConfigurePushDialog_ChangePushUriButton=C&hange...
-SimpleConfigurePushDialog_ChangeRefSpecButton=M&odify...
-SimpleConfigurePushDialog_ChangeUriButton=&Change...
-SimpleConfigurePushDialog_CopyRefSpecButton=C&opy
-SimpleConfigurePushDialog_DefaultPushNoRefspec=No Push Refspec, will push currently checked out branch instead.
-SimpleConfigurePushDialog_DeletePushUriButton=De&lete
-SimpleConfigurePushDialog_DeleteRefSpecButton=Dele&te
-SimpleConfigurePushDialog_DeleteUriButton=Re&move
-SimpleConfigurePushDialog_DetachedHeadMessage=Detached HEAD
-SimpleConfigurePushDialog_DialogMessage=In order to use a remote for push, you must specify at least one URI and at least one ref mapping
-SimpleConfigurePushDialog_DialogTitle=Configure push for remote ''{0}''
-SimpleConfigurePushDialog_DryRunButton=Dr&y-Run
-SimpleConfigurePushDialog_EditAdvancedButton=Ad&vanced...
-SimpleConfigurePushDialog_EmptyClipboardDialogMessage=The clipboard is empty
-SimpleConfigurePushDialog_EmptyClipboardDialogTitle=Nothing to Paste
-SimpleConfigurePushDialog_InvalidRefDialogMessage=Refspec {0} does not appear to be valid, do you still want to add it?
-SimpleConfigurePushDialog_InvalidRefDialogTitle=Invalid Ref
-SimpleConfigurePushDialog_MissingUriMessage=Please provide at least one URI
-SimpleConfigurePushDialog_NoRefSpecDialogMessage=The contents of the clipboard does not appear to be a refspec
-SimpleConfigurePushDialog_NoRefSpecDialogTitle=Not a Refspec
-SimpleConfigurePushDialog_PasteRefSpecButton=Pa&ste
-SimpleConfigurePushDialog_PushUrisLabel=Push URIs
-SimpleConfigurePushDialog_RefMappingGroup=Ref mappings
-SimpleConfigurePushDialog_RefSpecLabel=&Refspec:
-SimpleConfigurePushDialog_RemoteGroupTitle=Push Configuration for Remote ''{0}''
-SimpleConfigurePushDialog_RepositoryLabel=Repository:
-SimpleConfigurePushDialog_ReusedOriginWarning=Note that remote ''{0}'' is used from {1} other branches (see tooltip for a list)
-SimpleConfigurePushDialog_RevertButton=Re&vert
-SimpleConfigurePushDialog_SaveAndPushButton=Save and Push
-SimpleConfigurePushDialog_SaveButton=Save
-SimpleConfigurePushDialog_UriGroup=URI
-SimpleConfigurePushDialog_URILabel=&URI:
-SkipRebaseCommand_CancelDialogMessage=The skip operation was canceled
-SkipRebaseCommand_JobName=Skipping Rebase
-
-ValidationUtils_CanNotResolveRefMessage=Can not resolve {0}
-ValidationUtils_InvalidRefNameMessage={0} is not a valid name for a ref
-ValidationUtils_RefAlreadyExistsMessage=Ref {0} already exists
-ValidationUtils_RefNameConflictsWithExistingMessage=Name conflicts with existing refs: {0}
-ValidationUtils_PleaseEnterNameMessage=Please enter a name
-
-GitMergeEditorInput_CalculatingDiffTaskName=Calculating Differences
-GitMergeEditorInput_CheckingResourcesTaskName=Checking resources
-GitMergeEditorInput_MergeEditorTitle=Repository ''{0}'': Merging ''{1}'' into ''{2}''
-GitMergeEditorInput_WorkspaceHeader=Workspace Version
-GitModelIndex_index=<staged changes>
-
-GitModelWorkingTree_workingTree=<working tree>
-
-EgitUiEditorUtils_openFailed=Opening editor failed
-
-SimpleConfigureFetchDialog_AddRefSpecButton=A&dd...
-SimpleConfigureFetchDialog_BranchLabel=Branch:
-SimpleConfigureFetchDialog_ChangeRefSpecButton=M&odify...
-SimpleConfigureFetchDialog_ChangeUriButton=&Change...
-SimpleConfigureFetchDialog_CopyRefSpecButton=C&opy
-SimpleConfigureFetchDialog_DeleteRefSpecButton=Dele&te
-SimpleConfigureFetchDialog_DeleteUriButton=Re&move
-SimpleConfigureFetchDialog_DetachedHeadMessage=Detached HEAD
-SimpleConfigureFetchDialog_DialogMessage=In order to use a remote for fetch, you must specify a URI and at least one ref mapping
-SimpleConfigureFetchDialog_DialogTitle=Configure fetch for remote ''{0}''
-SimpleConfigureFetchDialog_DryRunButton=Dr&y-Run
-SimpleConfigureFetchDialog_EditAdvancedButton=Ad&vanced...
-SimpleConfigureFetchDialog_EmptyClipboardMessage=The clipboard is empty
-SimpleConfigureFetchDialog_InvalidRefDialogMessage=Refspec {0} does not appear to be valid, do you still want to add it?
-SimpleConfigureFetchDialog_InvalidRefDialogTitle=Invalid Ref
-SimpleConfigureFetchDialog_MissingMappingMessage=Please provide a ref mapping
-SimpleConfigureFetchDialog_MissingUriMessage=Please provide a URI
-SimpleConfigureFetchDialog_NothingToPasteMessage=Nothing to paste
-SimpleConfigureFetchDialog_NotRefSpecDialogMessage=The contents of the clipboard does not appear to be a refspec
-SimpleConfigureFetchDialog_NotRefSpecDialogTitle=Not a Refspec
-SimpleConfigureFetchDialog_PateRefSpecButton=&Paste
-SimpleConfigureFetchDialog_RefMappingGroup=Ref mappings
-SimpleConfigureFetchDialog_RefSpecLabel=&RefSpec:
-SimpleConfigureFetchDialog_RemoteGroupHeader=Fetch configuration for remote ''{0}''
-SimpleConfigureFetchDialog_RepositoryLabel=Repository:
-SimpleConfigureFetchDialog_ReusedRemoteWarning=Note that remote ''{0}'' is used from {1} other branches (see tooltip for a list)
-SimpleConfigureFetchDialog_RevertButton=Re&vert
-SimpleConfigureFetchDialog_SaveAndFetchButton=Save and Fetch
-SimpleConfigureFetchDialog_SaveButton=Save
-SimpleConfigureFetchDialog_UriLabel=&URI:
-SimpleConfigureFetchDialog_WindowTitle=Configure Fetch
-SimpleFetchActionHandler_NothingToFetchDialogMessage=Can not fetch anything: the currently checked-out branch is based on a local branch
-SimpleFetchActionHandler_NothingToFetchDialogTitle=Nothing to Fetch
-SimpleFetchRefSpecWizard_WizardTitle=Adding a Refspec for Fetch
-SimplePushActionHandler_NothingToPushDialogMessage=Can not push anything: the currently checked-out branch is based on a local branch
-SimplePushActionHandler_NothingToPushDialogTitle=Nothing to Push
-SimplePushSpecPage_message=Select target to push {0} to
-SimplePushSpecPage_pushAheadInfo={0} is {1} commits ahead of {2}
-SimplePushSpecPage_TargetRefName=Target Ref Name:
-SimplePushSpecPage_title=Select push destination
-SwitchToMenu_NewBranchMenuLabel=&New Branch...
-SwitchToMenu_OtherMenuLabel=&Other...
-GitActionContributor_ExpandAll=Expand All
-GitActionContributor_Push=Push
-GitActionContributor_Pull=Pull
-GitLabelProvider_UnableToRetrieveLabel=Unable to retrieve label for {0}
-GitVariableResolver_InternalError=Internal error
-GitVariableResolver_NoSelectedResource=No selected resource
-GitVariableResolver_VariableReferencesNonExistentResource=Variable references non-existent resource : {0}
-
-OpenWorkingFileAction_text=&Open
-OpenWorkingFileAction_tooltip=Open working file
-OpenWorkingFileAction_openWorkingFileShellTitle=Problems Opening Working File
-
-StagingView_UnstagedChanges=Unstaged Changes ({0})
-StagingView_ShowFileNamesFirst=Show File Names First
-StagingView_StagedChanges=Staged Changes ({0})
-StagingView_CommitMessage=Commit Message
-StagingView_Committer=Committer:
-StagingView_Author=Author:
-StagingView_Ammend_Previous_Commit=Amend Previous Commit
-StagingView_Add_Signed_Off_By=Add Signed-off-by
-StagingView_Add_Change_ID=Add Change-Id
-StagingView_Commit=Commit
-StagingView_CommitToolTip=Commit ({0})
-StagingView_CommitAndPush=Commit and Push
-StagingView_checkoutFailed=Checking out files failed
-StagingView_commitFailed=Commit failed
-StagingView_committingNotPossible=Committing is not possible
-StagingView_headCommitChanged=\# WARNING: head commit changed in the meantime
-StagingView_noStagedFiles=There are no staged files
-StagingView_NoSelectionTitle=No Repository Selected
-StagingView_OpenNewCommits=Open New Commits
-StagingView_ColumnLayout=Column Layout
-StagingView_Refresh=Refresh
-StagingView_LinkSelection=Link with Editor and Selection
-StagingView_exceptionTitle=Refresh Error
-StagingView_exceptionMessage=Errors occurred while applying processing change notifications.
-StagingView_replaceWithFileInGitIndex=Replace with File in Git Index
-StagingView_replaceWithHeadRevision=Replace with HEAD Revision
-StagingView_UnstageItemMenuLabel=Remove from Git Index
-StagingView_StageItemMenuLabel=Add to Git Index
-StagingView_IgnoreItemMenuLabel=Ignore
-StagingView_DeleteItemMenuLabel=Delete
-StagingViewContentProvider_SubmoduleError=Unhandled exception while analyzing submodules
-StashApplyCommand_applyFailed=Applying stashed commit ''{0}'' failed due to ''{1}''
-StashApplyCommand_jobTitle=Apply changes from stashed commit ''{0}''
-StashCreateCommand_jobTitle=Stashing local changes
-StashCreateCommand_messageEnterCommitMessage=Enter stash commit message (optional):
-StashCreateCommand_messageNoChanges=The repository does not contain any local changes to stash.
-StashCreateCommand_stashFailed=Stash create error
-StashCreateCommand_titleEnterCommitMessage=Commit Stash
-StashCreateCommand_titleNoChanges=No Changes
-StashDropCommand_confirmMessage=Are you sure you want to delete stashed commit stash@'{'{0}'}'?
-StashDropCommand_confirmTitle=Confirm Stashed Commit Deletion
-StashDropCommand_dropFailed=Dropping stashed commit ''{0}'' failed
-StashDropCommand_jobTitle=Dropping stashed commit ''{0}''
-SubmoduleAddCommand_AddError=Submodule add error
-SubmoduleAddCommand_JobTitle=Creating submodule ''{0}'' from ''{1}''
-SubmodulePathWizardPage_ErrorPathMustBeEmpty=Path must be an empty or non-existent directory
-SubmodulePathWizardPage_Message=Enter relative path to submodule
-SubmodulePathWizardPage_PathLabel=Submodule Path:
-SubmodulePathWizardPage_Title=Submodule Path
-SubmoduleSyncCommand_SyncError=Submodule configuration sync error
-SubmoduleSyncCommand_Title=Synchronized submodule configuration
-SubmoduleUpdateCommand_Title=Updating submodules
-SubmoduleUpdateCommand_UpdateError=Submodule update error
-
-SynchronizeWithMenu_custom=&Custom...
-SynchronizeFetchJob_JobName=Fetching changes before synchronization launch
-SynchronizeFetchJob_TaskName=Fetching changes for synchronization
-SynchronizeFetchJob_SubTaskName=Fetching changes from {0}
-SynchronizeFetchJob_FetchFailedTitle=Fetch from {0} Failed
-SynchronizeFetchJob_FetchFailedMessage=Fetch operation failed.\n\nSychronization will be continued based on data that are currently in repository.\n\nYou can disable fetching changes before synchronization in preferences:\nTeam > Git > {0}
-
-GitModelSynchonize_fetchGitDataJobName=Fetching data from git
-
-FetchChangeFromGerritCommand_noRepositorySelectedTitle=No Git project was selected
-FetchChangeFromGerritCommand_noRepositorySelectedMessage=To be able to fetch changes from Gerrit you need to select a project which is shared with a Git repository and which is configured with Gerrit as a remote repository
-
-RebasePulldownAction_Continue=&Continue
-RebasePulldownAction_Skip=&Skip
-RebasePulldownAction_Abort=&Abort
-
-SynchronizeCommand_jobName=Synchronizing {0} ...
-GitOpenInCompareAction_cannotRetrieveCommitWithId=Cannot retrieve commit with id {0} from repository {1}
-
-CloneFailureDialog_tile=Transport Error
-CloneFailureDialog_dontShowAgain=Don't show this dialog again
-CloneFailureDialog_checkList={0}\n\nPlease check:\nNetwork Connection settings\nNetwork Connection -> SSH2 Eclipse preferences\n\nYou may also need to restart Eclipse after making changes in preferences.
-
-GarbageCollectCommand_jobTitle=Collect garbage in {0}
-GarbageCollectCommand_failed=Garbage collection in repository {0} failed
-
-RepositoryStatistics_Description=Description
-RepositoryStatistics_LooseObjects=Loose objects
-RepositoryStatistics_NrOfObjects=Number of objects
-RepositoryStatistics_NrOfPackfiles=Number of packfiles
-RepositoryStatistics_NrOfRefs=Number of refs
-RepositoryStatistics_SpaceNeededOnFilesystem=Space needed on filesystem
-RepositoryStatistics_PackedObjects=Packed objects
-
-GitModelSynchronizeParticipant_initialScopeName=Git
