/*******************************************************************************
 * Copyright (c) 2014-2016 Red Hat 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
 *
 * Contributors:
 *     Mickael Istria (Red Hat Inc.) - initial API and implementation
 ******************************************************************************/
package org.eclipse.ui.internal.wizards.datatransfer;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;

import org.eclipse.core.resources.IContainer;
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.IWorkspace;
import org.eclipse.core.resources.IWorkspaceDescription;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
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.SubMonitor;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.jobs.JobGroup;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
import org.eclipse.ui.wizards.datatransfer.ProjectConfigurator;

/**
 * The {@link SmartImportJob} is a Job to import a given folder or archive. It
 * detects the nested projects in the given source and configure projects
 * according to the metadata it could find. The behavior is extensible, and
 * contributors can add a {@link ProjectConfigurator} strategy via extension
 * point to add support for more project kinds.
 *
 * @since 3.12
 *
 */
public class SmartImportJob extends Job {

	/*
	 * Input parameters
	 */
	private File rootDirectory;
	private Set<File> directoriesToImport;
	private Set<File> excludedDirectories;
	private boolean discardRootProject;
	private boolean deepChildrenDetection;
	private boolean configureProjects;
	private boolean reconfigureEclipseProjects;
	private IWorkingSet[] workingSets;

	/*
	 * working fields
	 */
	private IProject rootProject;
	private IWorkspaceRoot workspaceRoot;
	private ProjectConfiguratorExtensionManager configurationManager;
	private RecursiveImportListener listener;

	protected Map<File, List<ProjectConfigurator>> importProposals;
	private Map<IProject, List<ProjectConfigurator>> report;
	private Map<IPath, Exception> errors;

	private JobGroup crawlerJobGroup;

	/**
	 * Builds a new instance of the job
	 *
	 * @param rootDirectory
	 *            the root directory to import and analyze
	 * @param workingSets
	 *            working sets to assign to imported projects
	 * @param configureProjects
	 *            whether we want to configure projects (natures etc...)
	 *            according to their metadata
	 * @param recuriveChildrenDetection
	 *            whether to recurse for detection of nested projects
	 */
	public SmartImportJob(File rootDirectory, Set<IWorkingSet> workingSets, boolean configureProjects, boolean recuriveChildrenDetection) {
		super(rootDirectory.getAbsolutePath());
		this.workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
		this.rootDirectory = rootDirectory;
		if (workingSets != null) {
			this.workingSets = workingSets.toArray(new IWorkingSet[workingSets.size()]);
		} else {
			this.workingSets = new IWorkingSet[0];
		}
		this.configureProjects = configureProjects;
		this.deepChildrenDetection = recuriveChildrenDetection;
		this.report = Collections.synchronizedMap(new HashMap<IProject, List<ProjectConfigurator>>());
		this.errors = Collections.synchronizedMap(new HashMap<IPath, Exception>());
		this.crawlerJobGroup = new JobGroup(DataTransferMessages.SmartImportJob_detectAndConfigureProjects, 0, 1);
	}

	/**
	 * @return The root directory for the import operation
	 */
	public File getRoot() {
		return this.rootDirectory;
	}

	/**
	 * Sets the directories that have been detected by preliminary detection and that
	 * user has selected to import. Those will be imported and configured in any case.
	 * This does not impact output of {@link #getImportProposals(IProgressMonitor)}
	 * @param directories
	 */
	public void setDirectoriesToImport(Set<File> directories) {
		this.directoriesToImport = directories;
	}

	/**
	 * Set directories that users specifically configured as to NOT import.
	 * Projects UNDER those directories may be imported, but never project directly
	 * in one of those directories.
	 * This does not impact output of {@link #getImportProposals(IProgressMonitor)}
	 * @param directories
	 */
	public void setExcludedDirectories(Set<File> directories) {
		this.excludedDirectories = directories;
	}

	/**
	 * Adds a listener to be notified of progress (detection/configuration of
	 * sub-projects)
	 *
	 * @param listener
	 */
	public void setListener(RecursiveImportListener listener) {
		this.listener = listener;
	}

	@Override
	public IStatus run(IProgressMonitor monitor) {
		try {
			IWorkspace workspace = ResourcesPlugin.getWorkspace();
			IWorkspaceDescription description = workspace.getDescription();
			boolean isAutoBuilding = workspace.isAutoBuilding();
			if (isAutoBuilding) {
				description.setAutoBuilding(false);
				workspace.setDescription(description);
			}

			if (directoriesToImport != null) {
				this.deepChildrenDetection = false;
				SubMonitor loopMonitor = SubMonitor.convert(monitor,
						DataTransferMessages.SmartImportJob_configuringSelectedDirectories,
						directoriesToImport.size() * (configureProjects ? 3 : 2) + 1);
				Comparator<File> rootToLeafComparator = new Comparator<File>() {
					@Override
					public int compare(File arg0, File arg1) {
						int lengthDiff = arg0.getAbsolutePath().length() - arg1.getAbsolutePath().length();
						if (lengthDiff != 0) {
							return lengthDiff;
						}
						return arg0.compareTo(arg1);
					}
				};
				SortedSet<File> directories = new TreeSet<>(rootToLeafComparator);
				directories.addAll(this.directoriesToImport);
				SortedMap<File, IProject> leafToRootProjects = new TreeMap<>(Collections.reverseOrder(rootToLeafComparator));
				final Set<IProject> alreadyConfiguredProjects = new HashSet<>();
				loopMonitor.worked(1);
				for (final File directoryToImport : directories) {
					final boolean alreadyAnEclipseProject = new File(directoryToImport, IProjectDescription.DESCRIPTION_FILE_NAME).isFile();
					try {
						IProject newProject = toExistingOrNewProject(directoryToImport, loopMonitor.split(1),
								IResource.BACKGROUND_REFRESH);
						if (alreadyAnEclipseProject) {
							alreadyConfiguredProjects.add(newProject);
						}
						leafToRootProjects.put(directoryToImport, newProject);
						loopMonitor.worked(1);
					} catch (CouldNotImportProjectException ex) {
						Path path = new Path(directoryToImport.getAbsolutePath());
						if (listener != null) {
							listener.errorHappened(path, ex);
						}
						this.errors.put(path, ex);
					}
				}
				if (configureProjects) {
					JobGroup multiDirectoriesJobGroup = new JobGroup(
							DataTransferMessages.SmartImportJob_configuringSelectedDirectories, 20, 1);
					for (final IProject newProject : leafToRootProjects.values()) {
						Job directoryJob = new Job(
								NLS.bind(DataTransferMessages.SmartImportJob_configuring, newProject.getName())) {
							@Override
							protected IStatus run(IProgressMonitor aMonitor) {
								try {
									importProjectAndChildrenRecursively(newProject,
											!alreadyConfiguredProjects.contains(newProject), monitor);
									return Status.OK_STATUS;
								} catch (Exception ex) {
									return new Status(IStatus.ERROR, IDEWorkbenchPlugin.IDE_WORKBENCH, ex.getMessage(),
											ex);
								}
							}
						};
						// Job1 on path1 and Job2 on path2 can be run in parallel IFF path1 isn't a prefix of path2 and vice-versa
						directoryJob.setRule(new SubdirectoryOrSameNameSchedulingRule(newProject));
						directoryJob.setUser(true);
						directoryJob.setJobGroup(multiDirectoriesJobGroup);
						directoryJob.schedule();
					}
					multiDirectoriesJobGroup.join(0, loopMonitor.split(leafToRootProjects.size()));
				}


			} else { // no specific projects included, consider only root
				SubMonitor subMonitor = SubMonitor.convert(monitor, 3);
				File rootProjectFile = new File(this.rootDirectory, IProjectDescription.DESCRIPTION_FILE_NAME);
				boolean isRootANewProject = !rootProjectFile.isFile();
				this.rootProject = toExistingOrNewProject(this.rootDirectory, subMonitor, IResource.NONE);

				if (this.configureProjects) {
					importProjectAndChildrenRecursively(this.rootProject, isRootANewProject, subMonitor);

					if (isRootANewProject && rootProjectWorthBeingRemoved()) {
						Display.getDefault().syncExec(new Runnable() {
							@Override
							public void run() {
								discardRootProject = MessageDialog.openQuestion(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
										DataTransferMessages.SmartImportJob_discardRootProject_title,
										DataTransferMessages.SmartImportJob_discardRootProject_description);
							}
						});
						if (this.discardRootProject) {
							this.rootProject.delete(false, true, subMonitor);
							if (isRootANewProject) {
								rootProjectFile.delete();
							}
							this.report.remove(this.rootProject);
						}
					}
				}
			}

			if (isAutoBuilding) {
				description.setAutoBuilding(true);
				workspace.setDescription(description);
			}
		} catch (Exception ex) {
			return new Status(IStatus.ERROR, IDEWorkbenchPlugin.IDE_WORKBENCH, ex.getMessage(), ex);
		}
		return Status.OK_STATUS;
	}

	protected boolean rootProjectWorthBeingRemoved() {
		if (this.report.size() == 1) {
			return false;
		}
		List<ProjectConfigurator> rootProjectConfigurators = this.report.get(this.rootProject);
		if (rootProjectConfigurators.isEmpty()) {
			return true;
		}
		boolean areOnlyDummyConfigurators = true;
		for (ProjectConfigurator configurator : rootProjectConfigurators) {
			// TODO: semantics whether configurator is "strong enough" for a root project should be put inside configurator
			areOnlyDummyConfigurators &= (configurator instanceof EclipseProjectConfigurator || configurator instanceof EclipseWorkspaceConfigurator);
		}
		return areOnlyDummyConfigurators;
	}


	private final class CrawlFolderJob extends Job {
		private final IFolder childFolder;
		private final Set<IProject> res;

		private CrawlFolderJob(String name, IFolder childFolder, Set<IProject> res) {
			super(name);
			this.childFolder = childFolder;
			this.res = res;
		}

		@Override
		public IStatus run(IProgressMonitor progressMonitor) {
			SubMonitor subMonitor = null;
			if (progressMonitor instanceof SubMonitor) {
				subMonitor = (SubMonitor) progressMonitor;
			} else {
				subMonitor = SubMonitor.convert(progressMonitor);
			}
			try {
				Set<IProject> projectFromCurrentContainer = importProjectAndChildrenRecursively(childFolder, false,
						subMonitor);
				res.addAll(projectFromCurrentContainer);
				return Status.OK_STATUS;
			} catch (Exception ex) {
				return new Status(IStatus.ERROR, IDEWorkbenchPlugin.IDE_WORKBENCH, ex.getMessage(), ex);
			}
		}
	}

	private Set<IProject> searchAndImportChildrenProjectsRecursively(IContainer parentContainer, Set<IPath> directoriesToExclude, final IProgressMonitor progressMonitor) throws Exception {
		SubMonitor subMonitor = SubMonitor.convert(progressMonitor, parentContainer.members().length);
		for (IProject processedProjects : Collections.synchronizedSet(this.report.keySet())) {
			if (processedProjects.getLocation().equals(parentContainer.getLocation())) {
				return Collections.emptySet();
			}
		}
		parentContainer.refreshLocal(IResource.DEPTH_ONE, progressMonitor); // make sure we know all children
		Set<IFolder> childrenToProcess = new HashSet<>();
		final Set<IProject> res = Collections.synchronizedSet(new HashSet<IProject>());
		for (IResource childResource : parentContainer.members()) {
			if (childResource.getType() == IResource.FOLDER && !childResource.isDerived()) {
				boolean excluded = false;
				if (directoriesToExclude != null) {
					for (IPath excludedPath : directoriesToExclude) {
						if (!excludedPath.isPrefixOf(parentContainer.getLocation()) && excludedPath.isPrefixOf(childResource.getLocation())) {
							excluded = true;
						}
					}
				}
				if (!excluded) {
					childrenToProcess.add((IFolder)childResource);
				}
			}
		}

		Set<CrawlFolderJob> jobs = new HashSet<>();
		for (final IFolder childFolder : childrenToProcess) {
			CrawlFolderJob crawlerJob = new CrawlFolderJob(
					NLS.bind(DataTransferMessages.SmartImportJob_crawling, childFolder.getLocation().toString()),
					childFolder, res);
			if (crawlerJobGroup.getMaxThreads() == 0 || crawlerJobGroup.getActiveJobs().size() < crawlerJobGroup.getMaxThreads()) {
				crawlerJob.setJobGroup(crawlerJobGroup);
				jobs.add(crawlerJob);
				crawlerJob.schedule();
			} else {
				crawlerJob.run(subMonitor);
				subMonitor.worked(1);
			}
		}
		for (CrawlFolderJob job : jobs) {
			job.join(0, subMonitor.split(1));
		}
		subMonitor.done();
		return res;
	}

	private Set<IProject> importProjectAndChildrenRecursively(IContainer container, boolean forceFullProjectCheck,
			IProgressMonitor progressMonitor) throws Exception {
		int allWork = 30 + ProjectConfiguratorExtensionManager.getAllExtensionLabels().size() * 5;
		SubMonitor subMonitor = SubMonitor.convert(progressMonitor,
				NLS.bind(DataTransferMessages.SmartImportJob_inspecting,
						container.getLocation().toFile().getAbsolutePath()),
				allWork);
		Set<IProject> projectFromCurrentContainer = new HashSet<>();
		boolean isAlreadyAnEclipseProject = false;
		Set<ProjectConfigurator> mainProjectConfigurators = new HashSet<>();
		Set<IPath> excludedPaths = new HashSet<>();
		if (this.excludedDirectories != null) {
			for (File excludedDirectory : this.excludedDirectories) {
				excludedPaths.add(new Path(excludedDirectory.getAbsolutePath()));
			}
		}
		container.refreshLocal(IResource.DEPTH_INFINITE, progressMonitor);
		if (!forceFullProjectCheck) {
			EclipseProjectConfigurator eclipseProjectConfigurator = new EclipseProjectConfigurator();
			if (eclipseProjectConfigurator.shouldBeAnEclipseProject(container, subMonitor.split(1))) {
				isAlreadyAnEclipseProject = true;
			}
		}

		if (this.configurationManager == null) {
			this.configurationManager = new ProjectConfiguratorExtensionManager();
		}
		Collection<ProjectConfigurator> activeConfigurators = this.configurationManager.getAllActiveProjectConfigurators(container);
		Set<ProjectConfigurator> potentialSecondaryConfigurators = new HashSet<>();
		IProject project = null;
		for (ProjectConfigurator configurator : activeConfigurators) {
			// exclude Eclipse project configurator for root project if is new
			if (configurator instanceof EclipseProjectConfigurator && forceFullProjectCheck) {
				continue;
			}
			if (configurator.shouldBeAnEclipseProject(container, subMonitor.split(1))) {
				mainProjectConfigurators.add(configurator);
				if (project == null) {
					// Create project
					try {
						project = toExistingOrNewProject(container.getLocation().toFile(), subMonitor.split(1),
								IResource.BACKGROUND_REFRESH);
					} catch (CouldNotImportProjectException ex) {
						this.errors.put(container.getLocation(), ex);
						if (this.listener != null) {
							this.listener.errorHappened(container.getLocation(), ex);
						}
						return projectFromCurrentContainer;
					}
					projectFromCurrentContainer.add(project);
				}
			} else {
				potentialSecondaryConfigurators.add(configurator);
			}
		}

		if (!mainProjectConfigurators.isEmpty()) {
			project.refreshLocal(IResource.DEPTH_INFINITE, subMonitor.split(1));
		}
		for (ProjectConfigurator configurator : mainProjectConfigurators) {
			IProgressMonitor childMonitor = subMonitor.split(1);
			if (configurator instanceof EclipseProjectConfigurator || !isAlreadyAnEclipseProject || this.reconfigureEclipseProjects) {
				configurator.configure(project, excludedPaths, childMonitor);
				this.report.get(project).add(configurator);
				if (this.listener != null) {
					listener.projectConfigured(project, configurator);
				}
			}
			excludedPaths.addAll(toPathSet(configurator.getFoldersToIgnore(project, subMonitor.split(20))));
		}

		Set<IProject> allNestedProjects = new HashSet<>();
		if (deepChildrenDetection) {
			allNestedProjects.addAll( searchAndImportChildrenProjectsRecursively(container, excludedPaths, progressMonitor) );
			excludedPaths.addAll(toPathSet(allNestedProjects));
			projectFromCurrentContainer.addAll(allNestedProjects);
		}

		if (mainProjectConfigurators.isEmpty() && (!isAlreadyAnEclipseProject || forceFullProjectCheck)) {
			// Apply secondary configurators
			if (project == null) {
				// Create project
				try {
					project = toExistingOrNewProject(container.getLocation().toFile(), subMonitor.split(1),
							IResource.BACKGROUND_REFRESH);
				} catch (CouldNotImportProjectException ex) {
					this.errors.put(container.getLocation(), ex);
					if (this.listener != null) {
						this.listener.errorHappened(container.getLocation(), ex);
					}
					return projectFromCurrentContainer;
				}
				projectFromCurrentContainer.add(project);
			}
			project.refreshLocal(IResource.DEPTH_ONE, subMonitor.split(1));
			// At least depth one, maybe INFINITE is necessary
			progressMonitor.setTaskName(
					NLS.bind(DataTransferMessages.SmartImportJob_continuingConfiguration, project.getName()));
			for (ProjectConfigurator additionalConfigurator : potentialSecondaryConfigurators) {
				if (additionalConfigurator.canConfigure(project, excludedPaths, subMonitor.split(1))) {
					additionalConfigurator.configure(project, excludedPaths, subMonitor.split(1));
					this.report.get(project).add(additionalConfigurator);
					if (this.listener != null) {
						listener.projectConfigured(project, additionalConfigurator);
					}
					excludedPaths
							.addAll(toPathSet(additionalConfigurator.getFoldersToIgnore(project, subMonitor.split(1))));
				}
			}
		}
		subMonitor.done();
		return projectFromCurrentContainer;
	}

	private Set<IPath> toPathSet(Set<? extends IContainer> resources) {
		if (resources == null || resources.isEmpty()) {
			return Collections.emptySet();
		}
		Set<IPath> res = new HashSet<>();
		for (IContainer container : resources) {
			res.add(container.getLocation());
		}
		return res;
	}

	/**
	 * @param directory
	 * @param workingSets
	 * @param refreshMode One {@link IResource#BACKGROUND_REFRESH} for background refresh, or {@link IResource#NONE} for immediate refresh
	 * @return
	 * @throws Exception
	 */
	private IProject toExistingOrNewProject(File directory, IProgressMonitor progressMonitor, int refreshMode) throws CouldNotImportProjectException {
		try {
			SubMonitor subMonitor = SubMonitor.convert(progressMonitor, NLS.bind(
					DataTransferMessages.SmartImportJob_importingProjectIntoWorkspace, directory.getAbsolutePath()), 2);
			IProject project = projectAlreadyExistsInWorkspace(directory);
			if (project == null) {
				project = createOrImportProject(directory, subMonitor.split(1));
			}
			subMonitor.setWorkRemaining(1);

			project.open(refreshMode, subMonitor.split(1));
			if (!this.report.containsKey(project)) {
				this.report.put(project, new ArrayList<ProjectConfigurator>());
			}
			if (this.listener != null) {
				this.listener.projectCreated(project);
			}
			return project;
		} catch (Exception ex) {
			throw new CouldNotImportProjectException(directory, ex);
		}
	}


	private IProject projectAlreadyExistsInWorkspace(File directory) {
		for (IProject project : workspaceRoot.getProjects()) {
			if (project.getLocation().toFile().getAbsoluteFile().equals(directory.getAbsoluteFile())) {
				return project;
			}
		}
		return null;
	}

	private IProject createOrImportProject(File directory, IProgressMonitor progressMonitor) throws Exception {
		IProjectDescription desc = null;
		File expectedProjectDescriptionFile = new File(directory, IProjectDescription.DESCRIPTION_FILE_NAME);
		if (expectedProjectDescriptionFile.exists()) {
			desc = ResourcesPlugin.getWorkspace().loadProjectDescription(new Path(expectedProjectDescriptionFile.getAbsolutePath()));
			String expectedName = desc.getName();
			IProject projectWithSameName = this.workspaceRoot.getProject(expectedName);
			if (projectWithSameName.exists()) {
				if (projectWithSameName.getLocation().toFile().equals(directory)) {
					// project seems already there
					return projectWithSameName;
				}
				throw new CouldNotImportProjectException(directory,
						NLS.bind(DataTransferMessages.SmartImportProposals_anotherProjectWithSameNameExists_description, expectedName));
			}
		} else {
			String projectName = directory.getName();
			if (this.workspaceRoot.getProject(directory.getName()).exists()) {
				int i = 1;
				do {
					projectName = directory.getName() + '(' + i + ')';
					i++;
				} while (this.workspaceRoot.getProject(projectName).exists());
			}

			desc = ResourcesPlugin.getWorkspace().newProjectDescription(projectName);
		}
		desc.setLocation(new Path(directory.getAbsolutePath()));
		IProject res = workspaceRoot.getProject(desc.getName());
		res.create(desc, progressMonitor);
		PlatformUI.getWorkbench().getWorkingSetManager().addToWorkingSets(res, this.workingSets);
		return res;
	}

	/**
	 *
	 * @return the project found/created for the root folder
	 */
	public IProject getRootProject() {
		return this.rootProject;
	}

	/**
	 *
	 * @return The list of projects found/imported and the strategy that were
	 *         used in order to configure them.
	 */
	public Map<IProject, List<ProjectConfigurator>> getConfiguredProjects() {
		return this.report;
	}

	/**
	 * @return the import errors that happened.
	 */
	public Map<IPath, Exception> getErrors() {
		return this.errors;
	}

	/**
	 *
	 * @param monitor
	 * @return the proposals for the import operation.
	 */
	public Map<File, List<ProjectConfigurator>> getImportProposals(IProgressMonitor monitor) {
		if (!this.deepChildrenDetection) {
			Map<File, List<ProjectConfigurator>> res = new HashMap<>();
			res.put(rootDirectory, Collections.emptyList());
			return res;
		}
		if (this.importProposals == null) {
			Map<File, List<ProjectConfigurator>> res = new HashMap<>();
			if (this.configurationManager == null) {
				this.configurationManager = new ProjectConfiguratorExtensionManager();
			}
			List<ProjectConfigurator> activeConfigurators = configurationManager
					.getAllActiveProjectConfigurators(this.rootDirectory);
			SubMonitor loopMonitor = SubMonitor.convert(monitor, activeConfigurators.size());
			for (ProjectConfigurator configurator : activeConfigurators) {
				Set<File> supportedDirectories = configurator.findConfigurableLocations(
						SmartImportJob.this.rootDirectory,
						loopMonitor.split(1));
				if (supportedDirectories != null) {
					for (File supportedDirectory : supportedDirectories) {
						if (supportedDirectory.isDirectory()) {
							if (!res.containsKey(supportedDirectory)) {
								res.put(supportedDirectory, new ArrayList<ProjectConfigurator>());
							}
							res.get(supportedDirectory).add(configurator);
						} else {
							IDEWorkbenchPlugin.log("Project detection must return only directories.\n" //$NON-NLS-1$
									+ supportedDirectory + " is not a directory.\nContributed by " //$NON-NLS-1$
									+ configurator.getClass().getName());
						}
					}
				}
			}
			for (ProjectConfigurator configurator : activeConfigurators) {
				configurator.removeDirtyDirectories(res);
			}
			this.importProposals = res;
		}
		return this.importProposals;
	}

	/**
	 * @return whether the job is set to configure projects (set natures and
	 *         other).
	 */
	public boolean isConfigureProjects() {
		return this.configureProjects;
	}

	/**
	 *
	 * @return whether the job will look for nested projects in case no
	 *         directory is passed to {@link #setDirectoriesToImport(Set)}
	 */
	public boolean isDetectNestedProjects() {
		return this.deepChildrenDetection;
	}

	/**
	 * Sets whether the job should look for nested projects. This value is
	 * ignored if consumer specifies directories to import via
	 * {@link #setDirectoriesToImport(Set)}.
	 *
	 * @param detectNestedProjects
	 */
	public void setDetectNestedProjects(boolean detectNestedProjects) {
		this.deepChildrenDetection = detectNestedProjects;
	}

	/**
	 * Forget the initial import proposals.
	 */
	public void resetProposals() {
		this.importProposals = null;
	}

	/**
	 *
	 * @return The directories that will be crawled for import
	 */
	public Set<File> getDirectoriesToImport() {
		return this.directoriesToImport;
	}

	@Override
	public boolean belongsTo(Object family) {
		return family == SmartImportJob.class;
	}

}
