/*******************************************************************************
 * Copyright (c) 2014 Obeo.
 * All rights reserved. This program and the accompanying materials
 * are made available under the 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:
 *     Obeo - initial API and implementation
 *******************************************************************************/
package org.eclipse.emf.compare.git.pgm.internal.cmd;

import static org.eclipse.emf.compare.git.pgm.internal.Options.GIT_DIR_OPT;
import static org.eclipse.emf.compare.git.pgm.internal.Options.HELP_OPT;
import static org.eclipse.emf.compare.git.pgm.internal.Options.SHOW_STACK_TRACE_OPT;
import static org.eclipse.emf.compare.git.pgm.internal.exception.Die.DeathType.FATAL;
import static org.eclipse.emf.compare.git.pgm.internal.exception.Die.DeathType.SOFTWARE_ERROR;
import static org.eclipse.emf.compare.git.pgm.internal.util.EMFCompareGitPGMUtil.EOL;
import static org.eclipse.emf.compare.git.pgm.internal.util.EMFCompareGitPGMUtil.SEP;
import static org.eclipse.emf.compare.git.pgm.internal.util.EMFCompareGitPGMUtil.toFileWithAbsolutePath;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.cert.Certificate;
import java.util.Collection;

import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.compare.git.pgm.Returns;
import org.eclipse.emf.compare.git.pgm.internal.ProgressPageLog;
import org.eclipse.emf.compare.git.pgm.internal.args.CmdLineParserRepositoryBuilder;
import org.eclipse.emf.compare.git.pgm.internal.args.GitDirHandler;
import org.eclipse.emf.compare.git.pgm.internal.args.SetupFileOptionHandler;
import org.eclipse.emf.compare.git.pgm.internal.exception.ArgumentValidationError;
import org.eclipse.emf.compare.git.pgm.internal.exception.Die;
import org.eclipse.emf.compare.git.pgm.internal.exception.Die.DeathType;
import org.eclipse.emf.compare.git.pgm.internal.exception.Die.DiesOn;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.URIConverter;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.equinox.p2.metadata.ILicense;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.util.io.ThrowingPrintWriter;
import org.eclipse.oomph.base.provider.BaseEditUtil;
import org.eclipse.oomph.internal.setup.SetupPrompter;
import org.eclipse.oomph.setup.Index;
import org.eclipse.oomph.setup.InstallationTask;
import org.eclipse.oomph.setup.Product;
import org.eclipse.oomph.setup.ProductCatalog;
import org.eclipse.oomph.setup.ProductVersion;
import org.eclipse.oomph.setup.Project;
import org.eclipse.oomph.setup.SetupPackage;
import org.eclipse.oomph.setup.SetupTask;
import org.eclipse.oomph.setup.Trigger;
import org.eclipse.oomph.setup.VariableTask;
import org.eclipse.oomph.setup.WorkspaceTask;
import org.eclipse.oomph.setup.internal.core.SetupContext;
import org.eclipse.oomph.setup.internal.core.SetupTaskPerformer;
import org.eclipse.oomph.setup.internal.core.util.ECFURIHandlerImpl;
import org.eclipse.oomph.setup.internal.core.util.SetupUtil;
import org.eclipse.oomph.setup.log.ProgressLog;
import org.eclipse.oomph.setup.p2.P2Task;
import org.eclipse.oomph.util.Confirmer;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser;
import org.kohsuke.args4j.Option;

/**
 * Abstract class for any logical command.
 * 
 * @author <a href="mailto:arthur.daussy@obeo.fr">Arthur Daussy</a>
 */
@SuppressWarnings("restriction")
public abstract class AbstractLogicalCommand {

	/** Oomph option. */
	protected static final String PROP_SETUP_CONFIRM_SKIP = "oomph.setup.confirm.skip"; //$NON-NLS-1$

	/** Oomph option. */
	protected static final String PROP_SETUP_OFFLINE_STARTUP = "oomph.setup.offline.startup"; //$NON-NLS-1$

	/** Oomph option. */
	protected static final String PROP_SETUP_MIRRORS_STARTUP = "oomph.setup.mirrors.startup"; //$NON-NLS-1$

	/** VM Args option. */
	protected static final String VMARGS_OPTION = "-D"; //$NON-NLS-1$

	/** Buffer size of the array use to generate an unique id. */
	private static final int GEN_ID_BUFFER_SIZE = 1024;

	/** Eclipse string. */
	private static final String ECLIPSE = "eclipse"; //$NON-NLS-1$

	/**
	 * Holds true if a user has set the help option to true.
	 */
	@Option(name = HELP_OPT, usage = "Dispays help for this command.", aliases = {"-h" })
	private boolean help;

	/**
	 * Holds the Oomph model setup file.
	 */
	@Argument(index = 0, metaVar = "<setup>", required = true, usage = "Path to the setup file. The setup file is a Oomph model.", handler = SetupFileOptionHandler.class)
	private File setupFile;

	/**
	 * Holds true if the java stack trace should be displayed in the console if any.
	 */
	@Option(name = SHOW_STACK_TRACE_OPT, usage = "Use this option to display java stack trace in console on error.")
	private boolean showStackTrace;

	/**
	 * Holds git directory location.
	 */
	@Option(name = GIT_DIR_OPT, metaVar = "gitFolderPath", usage = "Path to the .git folder of your repository.", handler = GitDirHandler.class)
	private String gitdir;

	/**
	 * Name of this command.
	 */
	private String commandName;

	/**
	 * Writer to output to, typically this is standard output.
	 */
	private ThrowingPrintWriter out;

	/**
	 * Usage of this command. This field is filled only if the help parameter has been provided.
	 */
	private String usage;

	/**
	 * Git repository for this command to be executed in.
	 */
	private Repository repo;

	/**
	 * SetupTaskPerformer of this command.
	 */
	private SetupTaskPerformer performer;

	/**
	 * Log.
	 */
	private ProgressLog progressPageLog;

	/**
	 * Constructor.
	 */
	protected AbstractLogicalCommand() {
		// Force the command to be built in the CommandFactory.
	}

	/**
	 * Executes the command.
	 * 
	 * @return The {@link Returns} for this command.
	 * @throws Die
	 *             if the program stop prematurely.
	 * @throws IOException
	 *             propagation.
	 */
	public final Integer execute() throws Die, IOException {
		if (!help) {
			return internalRun();
		} else {
			out.print(usage);
		}
		return Returns.COMPLETE.code();
	}

	/**
	 * Builds this command.
	 * 
	 * @param args
	 *            The arguments for this command.
	 * @param environmentSetupURI
	 *            URI to the environment setup file.
	 * @throws Die
	 *             exception on error.
	 * @throws IOException
	 *             e
	 */
	public void build(Collection<String> args, URI environmentSetupURI) throws Die, IOException {

		repo = parseArgumentsAndBuildRepo(args);

		try {
			final String outputEncoding;
			if (repo != null) {
				outputEncoding = repo.getConfig().getString("i18n", null, "logOutputEncoding"); //$NON-NLS-1$ //$NON-NLS-2$
			} else {
				outputEncoding = null;
			}
			BufferedWriter outbufw;
			if (outputEncoding != null) {
				outbufw = new BufferedWriter(new OutputStreamWriter(System.out, outputEncoding));
			} else {
				outbufw = new BufferedWriter(new OutputStreamWriter(System.out));
			}
			out = new ThrowingPrintWriter(outbufw);
		} catch (IOException e) {
			throw new DiesOn(SOFTWARE_ERROR).displaying("Cannot create input stream").ready();
		}

		if (!help) {
			// CHECKSTYLE.OFF: IllegalCatch - No choice since Oomph launch such an exception
			try {
				// Loads eclipse environment setup model.
				performer = createSetupTaskPerformer(setupFile.getAbsolutePath(), environmentSetupURI);
				performer.perform();

				if (!performer.hasSuccessfullyPerformed()) {
					throw new DiesOn(DeathType.FATAL).displaying("Error durring Oomph operation").ready();
				}
			} catch (Die e) {
				throw e;
			} catch (Exception e) {
				throw new DiesOn(DeathType.FATAL).duedTo(e).ready();
			}
			// CHECKSTYLE.ON: IllegalCatch
		}

	}

	/**
	 * Returns the value of the show-stack-trace argument.
	 * 
	 * @return the value of the show-stack-trace argument.
	 */
	public boolean isShowStackTrace() {
		return showStackTrace;
	}

	/**
	 * Returns the user setup file associated with this command.
	 * 
	 * @return the user setup file associated with this command.
	 */
	public File getSetupFile() {
		return setupFile;
	}

	/**
	 * Flush the out stream. This is mainly use to handle premature exit.
	 * 
	 * @throws IOException
	 *             if any problem with the stream.
	 */
	public void flushOutW() throws IOException {
		if (out != null) {
			out.flush();
		}
	}

	/**
	 * Runs the command.
	 * 
	 * @return Return code.
	 * @throws Die
	 *             e
	 * @throws IOException
	 *             exception on error.
	 */
	protected abstract Integer internalRun() throws Die, IOException;

	/**
	 * Gets the git repository.
	 * 
	 * @return the repository this command uses.
	 */
	protected Repository getRepository() {
		return repo;
	}

	/**
	 * Gets the SetupTaskPerformer.
	 * 
	 * @return the SetupTaskPerformer.
	 */
	protected SetupTaskPerformer getPerformer() {
		return performer;
	}

	/**
	 * Parses the arguments related to this command. It also in charge of building the git repository.
	 * <p>
	 * Since the --git-dir option can be passed through the command line, the parser is also in charge of
	 * building the repository
	 * </p>
	 * 
	 * @param args
	 *            arguments.
	 * @return the Repository.
	 * @throws Die
	 *             if the program exits prematurely.
	 */
	protected Repository parseArgumentsAndBuildRepo(Collection<String> args) throws Die {
		final CmdLineParserRepositoryBuilder clp = CmdLineParserRepositoryBuilder
				.newJGitRepoBuilderCmdParser(this);
		try {
			clp.parseArgument(args);
		} catch (ArgumentValidationError err) {
			// Only throw an error if the user has not required help.
			if (!help) {
				if (err.getCause() instanceof Die) {
					// Do not wrap a Die exception
					throw (Die)err.getCause();
				} else {
					throw new DiesOn(FATAL).displaying(err.getMessage()).ready();
				}
			}
		} catch (CmdLineException err) {
			// Only throw an error if the user has not required help.
			if (!help) {
				ByteArrayOutputStream localOut = new ByteArrayOutputStream();
				PrintWriter printWritter = new PrintWriter(localOut);
				printUsage(err.getMessage() + " in:" + EOL, clp, printWritter);
				printWritter.close();
				throw new DiesOn(FATAL).displaying(localOut.toString()).ready();
			}
		}

		if (help) {
			// The user has used the help option. Saves the usage message for later
			ByteArrayOutputStream localOut = new ByteArrayOutputStream();
			PrintWriter printWritter = new PrintWriter(localOut);
			printUsage("", clp, printWritter);
			printWritter.close();
			usage = localOut.toString();
		}
		return clp.getRepo();
	}

	/**
	 * Prints the usage of this command.
	 * 
	 * @param message
	 *            a prefix message.
	 * @param clp
	 *            the current command line parser.
	 * @param printWritter
	 *            A {@link PrintWriter}.
	 */
	protected void printUsage(final String message, final CmdLineParser clp, PrintWriter printWritter) {
		printWritter.println(message);
		printWritter.print(commandName);
		clp.printSingleLineUsage(printWritter, null);
		printWritter.println();
		printWritter.println();

		clp.printUsage(printWritter, null);
		printWritter.println();

		printWritter.flush();
	}

	/**
	 * Returns the printer to write message in console.
	 * 
	 * @return {@link ThrowingPrintWriter}
	 */
	protected ThrowingPrintWriter out() {
		return out;
	}

	/**
	 * Sets the command name.
	 * 
	 * @param name
	 *            the command name.
	 */
	final void setCommandName(final String name) {
		commandName = name;
	}

	/**
	 * Create and configure the setup task performer to provision the eclipse environment.
	 * 
	 * @param userSetupFilePath
	 *            the path of the user setup model.
	 * @param environmentSetupURI
	 *            URI of the setup file that contains the environment used to execute the logical commands.
	 * @return a SetupTaskPerformer.
	 * @throws Die
	 *             e
	 * @throws IOException
	 *             e
	 */
	private SetupTaskPerformer createSetupTaskPerformer(String userSetupFilePath, URI environmentSetupURI)
			throws IOException, Die {
		// Load user setup model.
		ComposedAdapterFactory adapterFactory = new ComposedAdapterFactory(BaseEditUtil
				.createAdapterFactory());

		ResourceSet rs = SetupUtil.createResourceSet();
		rs.eAdapters().add(
				new AdapterFactoryEditingDomain.EditingDomainProvider(new AdapterFactoryEditingDomain(
						adapterFactory, null, rs)));
		rs.getLoadOptions().put(ECFURIHandlerImpl.OPTION_CACHE_HANDLING,
				ECFURIHandlerImpl.CacheHandling.CACHE_WITHOUT_ETAG_CHECKING);

		URI startupSetupURI = URI.createFileURI(userSetupFilePath);
		Resource startupSetup = null;
		// CHECKSTYLE.OFF: IllegalCatch - No choice since EMF launch can run a runtime exception if it does
		// not succeed in creating the resource. We want to handle this exception ourself
		try {
			startupSetup = rs.getResource(startupSetupURI, true);
		} catch (RuntimeException e) {
			// Does nothing handle later
		}
		// CHECKSTYLE.ON: IllegalCatch
		if (startupSetup == null) {
			throw new DiesOn(FATAL).displaying(userSetupFilePath + " is not a valid setup file").ready();
		}

		Object startupSetupRoot = EcoreUtil.getObjectByType(startupSetup.getContents(),
				SetupPackage.Literals.PROJECT);
		final Project startupSetupProject;
		if (startupSetupRoot instanceof Project) {
			startupSetupProject = (Project)startupSetupRoot;
		} else {
			throw new DiesOn(SOFTWARE_ERROR).displaying(
					"The root of the setup file should be a Setup::PROJECT").ready();
		}

		progressPageLog = new ProgressPageLog(System.out);

		Resource environmentSetup = rs.getResource(environmentSetupURI, true);
		Index eclipseSetupIndex = (Index)EcoreUtil.getObjectByType(environmentSetup.getContents(),
				SetupPackage.Literals.INDEX);

		handleWorkspace(startupSetupProject, eclipseSetupIndex);
		handleInstallation(startupSetupProject, eclipseSetupIndex);

		EList<ProductCatalog> productCatalogs = eclipseSetupIndex.getProductCatalogs();
		ProductCatalog catalog = productCatalogs.get(0);
		Product product = catalog.getProducts().get(0);
		ProductVersion productVersion = product.getVersions().get(0);

		// Add extra plugins to install from user setup model.
		for (SetupTask setupTask : startupSetupProject.getSetupTasks()) {
			if (setupTask instanceof P2Task) {
				SetupTask copy = EcoreUtil.copy(setupTask);
				catalog.getSetupTasks().add(copy);
			}
		}

		// Create Oomph setup context.
		final SetupContext setupContext = SetupContext.create(rs);
		setupContext.getInstallation().setProductVersion(productVersion);
		Trigger triggerBootstrap = Trigger.BOOTSTRAP;
		URIConverter uriConverter = rs.getURIConverter();
		SetupTaskPerformer aPerformer;
		// CHECKSTYLE.OFF: IllegalCatch - No choice since Oomph launch such an exception
		try {
			aPerformer = SetupTaskPerformer.create(uriConverter, SetupPrompter.CANCEL, triggerBootstrap,
					setupContext, false);
		} catch (Exception e) {
			throw new DiesOn(DeathType.ERROR).duedTo(e).displaying("Error during processing of setup mdoel")
					.ready();
		}
		// CHECKSTYLE.ON: IllegalCatch
		Confirmer confirmer = Confirmer.ACCEPT;
		aPerformer.put(ILicense.class, confirmer);
		aPerformer.put(Certificate.class, confirmer);
		aPerformer.setProgress(progressPageLog);
		aPerformer.setOffline(false);
		aPerformer.setMirrors(true);

		final String installationPath = getInstallationPath(startupSetupProject);
		if (installationPathContainsExistingEclipse(installationPath)) {
			aPerformer.getTriggeredSetupTasks().clear();
			progressPageLog.log("Existing eclipse environment found at : " + installationPath); //$NON-NLS-1$
		}

		return aPerformer;
	}

	/**
	 * Check if there is an existing eclipse environment at the given path.
	 * 
	 * @param installationPath
	 *            the given installation path.
	 * @return true if there is an existing eclipse environment at the given path, false otherwise.
	 */
	private boolean installationPathContainsExistingEclipse(String installationPath) {
		if (installationPath != null) {
			File file = new File(installationPath);
			if (file.exists()) {
				File[] eclipseFolder = file.listFiles(new FilenameFilter() {
					public boolean accept(File dir, String name) {
						return ECLIPSE.equals(name);
					}
				});
				if (eclipseFolder != null && eclipseFolder.length == 1) {
					return isEclipseIntallationFolder(eclipseFolder[0]);
				}
			}
		}
		return false;
	}

	/**
	 * Returns <code>true</code> if the file is a eclipse installation folder, <code>false</code> otherwise.
	 *
	 * @param eclipseFolder
	 *            file to test.
	 * @return <code>true</code> if the file is a eclipse installation folder, <code>false</code> otherwise.
	 */
	private boolean isEclipseIntallationFolder(File eclipseFolder) {
		if (eclipseFolder.exists()) {
			String[] eclipseExe = eclipseFolder.list(new FilenameFilter() {
				public boolean accept(File dir, String name) {
					return ECLIPSE.equals(name) || "eclipse.exe".equals(name); //$NON-NLS-1$
				}
			});
			if (eclipseExe.length == 1) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Handle the creation/reuse of the workspace path.
	 * 
	 * @param project
	 *            the root object of the user model.
	 * @param index
	 *            the root object of the environment model.
	 * @throws IOException
	 *             e
	 * @throws Die
	 *             e
	 */
	private void handleWorkspace(Project project, Index index) throws IOException, Die {
		final String workspaceLocation;
		if (modelDefinesWorkspacePath(project)) {
			workspaceLocation = getWorkspacePath(project);
		} else {
			workspaceLocation = genWorkspacePath(project);
		}

		for (ProductCatalog productCatalog : index.getProductCatalogs()) {
			for (SetupTask setupTask : productCatalog.getSetupTasks()) {
				if (setupTask instanceof WorkspaceTask) {
					((WorkspaceTask)setupTask).setLocation(workspaceLocation);
					return;
				}
			}
		}
	}

	/**
	 * Handle the creation/reuse of the installation path.
	 * 
	 * @param project
	 *            the root object of the user model.
	 * @param index
	 *            the root object of the environment model.
	 * @throws IOException
	 *             e
	 * @throws Die
	 *             e
	 */
	private void handleInstallation(Project project, Index index) throws IOException, Die {
		final String installationLocation;
		if (modelDefinesWorkspacePath(project)) {
			installationLocation = getInstallationPath(project);
		} else {
			installationLocation = genInstallationPath(project);
		}

		for (ProductCatalog productCatalog : index.getProductCatalogs()) {
			for (SetupTask setupTask : productCatalog.getSetupTasks()) {
				if (setupTask instanceof InstallationTask) {
					((InstallationTask)setupTask).setLocation(installationLocation);
					return;
				}
			}
		}
	}

	/**
	 * Returns true if the given Project contains a variable task with a non null workspace location.
	 * 
	 * @param project
	 *            the given Project.
	 * @return true if the given Project contains a variable task with a non null workspace location, false
	 *         otherwise.
	 */
	private boolean modelDefinesWorkspacePath(Project project) {
		String workspacePath = getWorkspacePath(project);
		if (workspacePath != null) {
			return true;
		}
		return false;
	}

	/**
	 * Search a variable task with name "workspace.location" in the given Project.
	 * 
	 * @param project
	 *            the given Project.
	 * @return the variable task if found, null otherwise.
	 */
	private VariableTask getVariableTaskForWorkspace(Project project) {
		for (SetupTask setupTask : project.getSetupTasks()) {
			if (setupTask instanceof VariableTask) {
				if ("workspace.location".equals(((VariableTask)setupTask).getName())) { //$NON-NLS-1$
					return (VariableTask)setupTask;
				}
			}
		}
		return null;
	}

	/**
	 * Search a variable task with name "installation.location" in the given Project.
	 * 
	 * @param project
	 *            the given Project.
	 * @return the variable task if found, null otherwise.
	 */
	private VariableTask getVariableTaskForInstallation(Project project) {
		for (SetupTask setupTask : project.getSetupTasks()) {
			if (setupTask instanceof VariableTask) {
				if ("installation.location".equals(((VariableTask)setupTask).getName())) { //$NON-NLS-1$
					return (VariableTask)setupTask;
				}
			}
		}
		return null;
	}

	/**
	 * Search a workspace task in the given Project. If found, return his location attribute value.
	 * 
	 * @param project
	 *            the given Project.
	 * @return the location attribute value of the workspace task if found, null otherwise.
	 */
	private String getWorkspacePath(Project project) {
		final String path;
		final VariableTask task = getVariableTaskForWorkspace(project);
		if (task != null) {
			String resourcePath = project.eResource().getURI().toFileString();
			String resourceBasePath = resourcePath.substring(0, resourcePath.lastIndexOf(SEP));
			path = toFileWithAbsolutePath(resourceBasePath, task.getValue()).toString();
		} else {
			path = null;
		}

		return path;
	}

	/**
	 * Search an installation task in the given Project. If found, return his location attribute value.
	 * 
	 * @param project
	 *            the given Project.
	 * @return the location attribute value of the installation task if found, null otherwise.
	 */
	private String getInstallationPath(Project project) {
		final String path;
		final VariableTask task = getVariableTaskForInstallation(project);
		if (task != null) {
			String resourcePath = project.eResource().getURI().toFileString();
			String resourceBasePath = resourcePath.substring(0, resourcePath.lastIndexOf(SEP));
			path = toFileWithAbsolutePath(resourceBasePath, task.getValue()).toString();
		} else {
			path = null;
		}
		return path;
	}

	/**
	 * Generates a unique id in the temporary folder of the system according to the given Project. If the
	 * generated id already exists (cause a command already been called with the same Project), it is reused.
	 * 
	 * @param project
	 *            the given Project.
	 * @return the location of the workspace.
	 * @throws IOException
	 *             e
	 * @throws Die
	 *             e
	 */
	private String genWorkspacePath(Project project) throws IOException, Die {
		String id = generateIDForSetup(project.eResource().getURI().toFileString());
		File ws = createOrGetTempDir("emfcWs" + id); //$NON-NLS-1$
		return ws.getAbsolutePath();
	}

	/**
	 * Generates a unique id in the temporary folder of the system according to the given Project. If the
	 * generated id already exists (cause a command already been called with the same Project), it is reused.
	 * 
	 * @param project
	 *            the given Project.
	 * @return the location of the workspace.
	 * @throws IOException
	 *             e
	 * @throws Die
	 *             e
	 */
	private String genInstallationPath(Project project) throws IOException, Die {
		String id = generateIDForSetup(project.eResource().getURI().toFileString());
		File ws = createOrGetTempDir("emfcInstall" + id); //$NON-NLS-1$
		return ws.getAbsolutePath();
	}
	/**
	 * Creates a temporary directory in the system temp directory.
	 * 
	 * @param name
	 *            the name of the temp directory to create.
	 * @return the new created directory.
	 */
	private static File createOrGetTempDir(String name) {
		final File baseDir = new File(System.getProperty("java.io.tmpdir")); //$NON-NLS-1$
		final String baseName = name;

		for (int counter = 0; counter < 10000; counter++) {
			final File tempDir = new File(baseDir, baseName);
			if (tempDir.exists()) {
				return tempDir;
			}
			if (tempDir.mkdir()) {
				return tempDir;
			}
		}
		throw new IllegalStateException("Failed to create directory within " + 10000 + " attempts (tried "
				+ baseName + "0 to " + baseName + (10000 - 1) + ')');
	}

	/**
	 * Generate a unique ID for the a given file.
	 * 
	 * @param setupFilePath
	 *            the absolute path of the given file.
	 * @return a unique ID for the a given file.
	 * @throws IOException
	 *             e
	 * @throws Die
	 *             On any other program error.
	 */
	private static String generateIDForSetup(String setupFilePath) throws IOException, Die {
		File f = new File(setupFilePath);
		MessageDigest digest;
		try {
			digest = MessageDigest.getInstance("SHA-1"); //$NON-NLS-1$
		} catch (NoSuchAlgorithmException e) {
			throw new DiesOn(DeathType.ERROR).duedTo(e).ready();
		}
		FileInputStream inputStream = new FileInputStream(f);
		byte[] bytesBuffer = new byte[GEN_ID_BUFFER_SIZE];
		int bytesRead = -1;

		while ((bytesRead = inputStream.read(bytesBuffer)) != -1) {
			digest.update(bytesBuffer, 0, bytesRead);
		}
		inputStream.close();

		byte[] hashedBytes = digest.digest();

		return convertByteArrayToHexString(hashedBytes);
	}

	/**
	 * Converts an array of bytes into a string of hexadecimal values.
	 * 
	 * @param arrayBytes
	 *            the given array of bytes.
	 * @return a string of hexadecimal values.
	 */
	private static String convertByteArrayToHexString(byte[] arrayBytes) {
		StringBuffer stringBuffer = new StringBuffer();
		for (int i = 0; i < arrayBytes.length; i++) {
			// CHECKSTYLE.OFF: MagicNumber
			stringBuffer.append(Integer.toString((arrayBytes[i] & 0xff) + 0x100, 16).substring(1));
			// CHECKSTYLE.ON: MagicNumber
		}
		return stringBuffer.toString();
	}

	/**
	 * Stream goobler.
	 * 
	 * @author <a href="mailto:axel.richard@obeo.fr">Axel Richard</a>
	 */
	class StreamGobbler implements Runnable {
		/** The stream. */
		private InputStream is;

		/**
		 * Reads everything from is until empty.
		 * 
		 * @param is
		 *            the stream to read.
		 */
		StreamGobbler(InputStream is) {
			this.is = is;
		}

		/**
		 * {@inheritDoc}.
		 */
		public void run() {
			try {
				InputStreamReader isr = new InputStreamReader(is);
				BufferedReader br = new BufferedReader(isr);
				String line = null;
				while ((line = br.readLine()) != null) {
					// performer.log(line);
					out().println(line);
				}
			} catch (IOException ioe) {
				ioe.printStackTrace();
			}
		}
	}
}
