/*******************************************************************************
 * 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.ui.internal.synchronize.mapping;

import static org.eclipse.jgit.lib.ObjectId.zeroId;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.resources.mapping.ResourceTraversal;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.egit.core.Activator;
import org.eclipse.egit.ui.internal.synchronize.model.GitModelTree;
import org.eclipse.jgit.lib.AnyObjectId;
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.jgit.treewalk.filter.TreeFilter;

class GitTreeTraversal extends ResourceTraversal {

	public GitTreeTraversal(GitModelTree modelTree) {
		this(modelTree.getRepository(), modelTree.getBaseId(), modelTree
				.getRemoteId(), modelTree.getLocation());
	}

	public GitTreeTraversal(Repository repo, RevCommit commit) {
		this(repo, commit.getParent(0).getTree().getId(), commit.getTree()
				.getId(), new Path(repo.getWorkTree().toString()));
	}

	private GitTreeTraversal(Repository repo, AnyObjectId baseId,
			AnyObjectId actualId, IPath path) {
		super(getResourcesImpl(repo, path, baseId, actualId),
				IResource.DEPTH_INFINITE, IResource.NONE);
	}

	private static IResource[] getResourcesImpl(Repository repo, IPath path,
			AnyObjectId baseId, AnyObjectId remoteId) {
		if (remoteId.equals(zeroId()))
			return new IResource[0];

		TreeWalk tw = new TreeWalk(repo);
		List<IResource> result = new ArrayList<IResource>();
		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();

		tw.reset();
		tw.setRecursive(false);
		tw.setFilter(TreeFilter.ANY_DIFF);
		try {
			if (!baseId.equals(zeroId()))
				tw.addTree(baseId);
			int actualNth = tw.addTree(remoteId);

			while (tw.next()) {
				int objectType = tw.getFileMode(actualNth).getObjectType();
				IPath childPath = path.append(tw.getNameString());

				IResource resource = null;
				if (objectType == Constants.OBJ_BLOB)
					resource = root.getFileForLocation(childPath);
				else if (objectType == Constants.OBJ_TREE)
					resource = root.getContainerForLocation(childPath);

				if (resource != null)
					result.add(resource);
			}
		} catch (IOException e) {
			Activator.logError(e.getMessage(), e);
		}

		return result.toArray(new IResource[result.size()]);
	}
}

@@ -1612,70 +1612,8 @@
 mmit
-.getParent(0).getTree().getId(), commit.getTree()%0A%09%09%09%09.getId()
 , ne
@@ -1788,22 +1788,16 @@
 pl(repo,
- path,
  baseId,
@@ -1805,16 +1805,22 @@
 actualId
+, path
 ),%0A%09%09%09%09I
@@ -1874,16 +1874,563 @@
 private 
+GitTreeTraversal(Repository repo, RevCommit commit, IPath path) %7B%0A%09%09super(getResourcesImpl(repo, commit, path), IResource.DEPTH_INFINITE,%0A%09%09%09%09IResource.NONE);%0A%09%7D%0A%0A%09private static IResource%5B%5D getResourcesImpl(Repository repo,%0A%09%09%09RevCommit commit, IPath path) %7B%0A%09%09AnyObjectId baseId;%0A%09%09RevCommit%5B%5D parents = commit.getParents();%0A%09%09if (parents.length %3E 0)%0A%09%09%09baseId = parents%5B0%5D.getTree().getId();%0A%09%09else%0A%09%09%09baseId = zeroId();%0A%0A%09%09AnyObjectId remoteId = commit.getTree().getId();%0A%0A%09%09return getResourcesImpl(repo, baseId, remoteId, path);%0A%09%7D%0A%0A%09private 
 static I
@@ -2472,28 +2472,16 @@
 ory repo
-, IPath path
 ,%0A%09%09%09Any
@@ -2517,16 +2517,28 @@
 remoteId
+, IPath path
 ) %7B%0A%09%09if

Fix IndexOutOfBoundException in GitTreeTraversal