/*******************************************************************************
 * Copyright (c) 2000, 2005 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
 *******************************************************************************/
package org.eclipse.ui.actions;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileInfo;
import org.eclipse.core.filesystem.IFileStore;
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.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.resources.WorkspaceJob;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
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.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IInputValidator;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.window.Window;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.ContainerGenerator;
import org.eclipse.ui.dialogs.IOverwriteQuery;
import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
import org.eclipse.ui.internal.ide.StatusUtil;
import org.eclipse.ui.internal.ide.dialogs.IDEResourceInfoUtils;
import org.eclipse.ui.wizards.datatransfer.FileStoreStructureProvider;
import org.eclipse.ui.wizards.datatransfer.ImportOperation;

/**
 * Perform the copy of file and folder resources from the clipboard when paste
 * action is invoked.
 * <p>
 * This class may be instantiated; it is not intended to be subclassed.
 * </p>
 */
public class CopyFilesAndFoldersOperation {

	/**
	 * Status containing the errors detected when running the operation or
	 * <code>null</code> if no errors detected.
	 */
	private MultiStatus errorStatus;

	/**
	 * The parent shell used to show any dialogs.
	 */
	private Shell messageShell;

	/**
	 * Whether or not the copy has been canceled by the user.
	 */
	private boolean canceled = false;

	/**
	 * Overwrite all flag.
	 */
	private boolean alwaysOverwrite = false;

	/**
	 * Returns a new name for a copy of the resource at the given path in the
	 * given workspace. This name is determined automatically.
	 * 
	 * @param originalName
	 *            the full path of the resource
	 * @param workspace
	 *            the workspace
	 * @return the new full path for the copy
	 */
	static IPath getAutoNewNameFor(IPath originalName, IWorkspace workspace) {
		int counter = 1;
		String resourceName = originalName.lastSegment();
		IPath leadupSegment = originalName.removeLastSegments(1);

		while (true) {
			String nameSegment;

			if (counter > 1)
				nameSegment = NLS
						.bind(
								IDEWorkbenchMessages.CopyFilesAndFoldersOperation_copyNameTwoArgs,
								new Integer(counter), resourceName);
			else
				nameSegment = NLS
						.bind(
								IDEWorkbenchMessages.CopyFilesAndFoldersOperation_copyNameOneArg,
								resourceName);

			IPath pathToTry = leadupSegment.append(nameSegment);

			if (!workspace.getRoot().exists(pathToTry))
				return pathToTry;

			counter++;
		}
	}

	/**
	 * Creates a new operation initialized with a shell.
	 * 
	 * @param shell
	 *            parent shell for error dialogs
	 */
	public CopyFilesAndFoldersOperation(Shell shell) {
		messageShell = shell;
	}

	/**
	 * Returns whether this operation is able to perform on-the-fly
	 * auto-renaming of resources with name collisions.
	 * 
	 * @return <code>true</code> if auto-rename is supported, and
	 *         <code>false</code> otherwise
	 */
	protected boolean canPerformAutoRename() {
		return true;
	}

	/**
	 * Returns the message for querying deep copy/move of a linked resource.
	 * 
	 * @param source
	 *            resource the query is made for
	 * @return the deep query message
	 */
	protected String getDeepCheckQuestion(IResource source) {
		return NLS
				.bind(
						IDEWorkbenchMessages.CopyFilesAndFoldersOperation_deepCopyQuestion,
						source.getFullPath().makeRelative());
	}

	/**
	 * Checks whether the infos exist.
	 * 
	 * @param stores
	 *            the file infos to test
	 * @return Multi status with one error message for each missing file.
	 */
	IStatus checkExist(IFileStore[] stores) {
		MultiStatus multiStatus = new MultiStatus(PlatformUI.PLUGIN_ID,
				IStatus.OK, getProblemsMessage(), null);

		for (int i = 0; i < stores.length; i++) {
			if (stores[i].fetchInfo().exists() == false) {
				String message = NLS
						.bind(
								IDEWorkbenchMessages.CopyFilesAndFoldersOperation_resourceDeleted,
								stores[i].getName());
				IStatus status = new Status(IStatus.ERROR,
						PlatformUI.PLUGIN_ID, IStatus.OK, message, null);
				multiStatus.add(status);
			}
		}
		return multiStatus;
	}

	/**
	 * Checks whether the resources with the given names exist.
	 * 
	 * @param resources
	 *            IResources to checl
	 * @return Multi status with one error message for each missing file.
	 */
	IStatus checkExist(IResource[] resources) {
		MultiStatus multiStatus = new MultiStatus(PlatformUI.PLUGIN_ID,
				IStatus.OK, getProblemsMessage(), null);

		for (int i = 0; i < resources.length; i++) {
			IResource resource = resources[i];
			if (resource != null) {
				URI location = resource.getLocationURI();
				String message = null;
				if (location != null) {
					IFileInfo info = IDEResourceInfoUtils.getFileInfo(location);
					if (info == null || info.exists() == false) {
						if (resource.isLinked()) {
							message = NLS
									.bind(
											IDEWorkbenchMessages.CopyFilesAndFoldersOperation_missingLinkTarget,
											resource.getName());
						} else {
							message = NLS
									.bind(
											IDEWorkbenchMessages.CopyFilesAndFoldersOperation_resourceDeleted,
											resource.getName());
						}
					}
				}
				if (message != null) {
					IStatus status = new Status(IStatus.ERROR,
							PlatformUI.PLUGIN_ID, IStatus.OK, message, null);
					multiStatus.add(status);
				}
			}
		}
		return multiStatus;
	}

	/**
	 * Check if the user wishes to overwrite the supplied resource or all
	 * resources.
	 * 
	 * @param source
	 *            the source resource
	 * @param destination
	 *            the resource to be overwritten
	 * @return one of IDialogConstants.YES_ID, IDialogConstants.YES_TO_ALL_ID,
	 *         IDialogConstants.NO_ID, IDialogConstants.CANCEL_ID indicating
	 *         whether the current resource or all resources can be overwritten,
	 *         or if the operation should be canceled.
	 */
	private int checkOverwrite(final IResource source,
			final IResource destination) {
		final int[] result = new int[1];

		// Dialogs need to be created and opened in the UI thread
		Runnable query = new Runnable() {
			public void run() {
				String message;
				int resultId[] = { IDialogConstants.YES_ID,
						IDialogConstants.YES_TO_ALL_ID, IDialogConstants.NO_ID,
						IDialogConstants.CANCEL_ID };
				String labels[] = new String[] { IDialogConstants.YES_LABEL,
						IDialogConstants.YES_TO_ALL_LABEL,
						IDialogConstants.NO_LABEL,
						IDialogConstants.CANCEL_LABEL };

				if (destination.getType() == IResource.FOLDER) {
					if (homogenousResources(source, destination)) {
						message = NLS
								.bind(
										IDEWorkbenchMessages.CopyFilesAndFoldersOperation_overwriteMergeQuestion,
										destination.getFullPath()
												.makeRelative());
					} else {
						if (destination.isLinked()) {
							message = NLS
									.bind(
											IDEWorkbenchMessages.CopyFilesAndFoldersOperation_overwriteNoMergeLinkQuestion,
											destination.getFullPath()
													.makeRelative());
						} else {
							message = NLS
									.bind(
											IDEWorkbenchMessages.CopyFilesAndFoldersOperation_overwriteNoMergeNoLinkQuestion,
											destination.getFullPath()
													.makeRelative());
						}
						resultId = new int[] { IDialogConstants.YES_ID,
								IDialogConstants.NO_ID,
								IDialogConstants.CANCEL_ID };
						labels = new String[] { IDialogConstants.YES_LABEL,
								IDialogConstants.NO_LABEL,
								IDialogConstants.CANCEL_LABEL };
					}
				} else {
					String[] bindings = new String[] {
							IDEResourceInfoUtils.getLocationText(destination),
							IDEResourceInfoUtils
									.getDateStringValue(destination),
							IDEResourceInfoUtils.getLocationText(source),
							IDEResourceInfoUtils.getDateStringValue(source) };
					message = NLS
							.bind(
									IDEWorkbenchMessages.CopyFilesAndFoldersOperation_overwriteWithDetailsQuestion,
									bindings);
				}
				MessageDialog dialog = new MessageDialog(
						messageShell,
						IDEWorkbenchMessages.CopyFilesAndFoldersOperation_resourceExists,
						null, message, MessageDialog.QUESTION, labels, 0);
				dialog.open();
				if (dialog.getReturnCode() == SWT.DEFAULT) {
					// A window close returns SWT.DEFAULT, which has to be
					// mapped to a cancel
					result[0] = IDialogConstants.CANCEL_ID;
				} else {
					result[0] = resultId[dialog.getReturnCode()];
				}
			}
		};
		messageShell.getDisplay().syncExec(query);
		return result[0];
	}

	/**
	 * Recursively collects existing files in the specified destination path.
	 * 
	 * @param destinationPath
	 *            destination path to check for existing files
	 * @param copyResources
	 *            resources that may exist in the destination
	 * @param existing
	 *            holds the collected existing files
	 */
	private void collectExistingReadonlyFiles(IPath destinationPath,
			IResource[] copyResources, ArrayList existing) {
		IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();

		for (int i = 0; i < copyResources.length; i++) {
			IResource source = copyResources[i];
			IPath newDestinationPath = destinationPath.append(source.getName());
			IResource newDestination = workspaceRoot
					.findMember(newDestinationPath);
			IFolder folder;

			if (newDestination == null) {
				continue;
			}
			folder = getFolder(newDestination);
			if (folder != null) {
				IFolder sourceFolder = getFolder(source);

				if (sourceFolder != null) {
					try {
						collectExistingReadonlyFiles(newDestinationPath,
								sourceFolder.members(), existing);
					} catch (CoreException exception) {
						recordError(exception);
					}
				}
			} else {
				IFile file = getFile(newDestination);

				if (file != null) {
					if (file.isReadOnly()) {
						existing.add(file);
					}
					if (getValidateConflictSource()) {
						IFile sourceFile = getFile(source);
						if (sourceFile != null) {
							existing.add(sourceFile);
						}
					}
				}
			}
		}
	}

	/**
	 * Copies the resources to the given destination. This method is called
	 * recursively to merge folders during folder copy.
	 * 
	 * @param resources
	 *            the resources to copy
	 * @param destination
	 *            destination to which resources will be copied
	 * @param subMonitor
	 *            a progress monitor for showing progress and for cancelation
	 */
	protected void copy(IResource[] resources, IPath destination,
			IProgressMonitor subMonitor) throws CoreException {

		subMonitor
				.beginTask(
						IDEWorkbenchMessages.CopyFilesAndFoldersOperation_CopyResourcesTask,
						resources.length);

		for (int i = 0; i < resources.length; i++) {
			IResource source = resources[i];
			IPath destinationPath = destination.append(source.getName());
			IWorkspace workspace = source.getWorkspace();
			IWorkspaceRoot workspaceRoot = workspace.getRoot();
			IResource existing = workspaceRoot.findMember(destinationPath);
			if (source.getType() == IResource.FOLDER && existing != null) {
				// the resource is a folder and it exists in the destination,
				// copy the
				// children of the folder.
				if (homogenousResources(source, existing)) {
					IResource[] children = ((IContainer) source).members();
					copy(children, destinationPath, new SubProgressMonitor(
							subMonitor, 1));
				} else {
					// delete the destination folder, copying a linked folder
					// over an unlinked one or vice versa. Fixes bug 28772.
					delete(existing, new SubProgressMonitor(subMonitor, 0));
					source.copy(destinationPath, IResource.SHALLOW,
							new SubProgressMonitor(subMonitor, 1));
				}
			} else {
				if (existing != null) {
					if (homogenousResources(source, existing))
						copyExisting(source, existing, new SubProgressMonitor(
								subMonitor, 1));
					else {
						// Copying a linked resource over unlinked or vice
						// versa.
						// Can't use setContents here. Fixes bug 28772.
						delete(existing, new SubProgressMonitor(subMonitor, 0));
						source.copy(destinationPath, IResource.SHALLOW,
								new SubProgressMonitor(subMonitor, 1));
					}
				} else {
					source.copy(destinationPath, IResource.SHALLOW,
							new SubProgressMonitor(subMonitor, 1));

				}

				if (subMonitor.isCanceled()) {
					throw new OperationCanceledException();
				}
			}
		}
	}

	/**
	 * Sets the content of the existing file to the source file content.
	 * 
	 * @param source
	 *            source file to copy
	 * @param existing
	 *            existing file to set the source content in
	 * @param subMonitor
	 *            a progress monitor for showing progress and for cancelation
	 * @throws CoreException
	 *             setContents failed
	 */
	private void copyExisting(IResource source, IResource existing,
			IProgressMonitor subMonitor) throws CoreException {
		IFile existingFile = getFile(existing);

		if (existingFile != null) {
			IFile sourceFile = getFile(source);

			if (sourceFile != null) {
				existingFile.setContents(sourceFile.getContents(),
						IResource.KEEP_HISTORY, new SubProgressMonitor(
								subMonitor, 0));
			}
		}
	}

	/**
	 * Copies the given resources to the destination. The current Thread is
	 * halted while the resources are copied using a WorkspaceModifyOperation.
	 * This method should be called from the UIThread.
	 * 
	 * @param resources
	 *            the resources to copy
	 * @param destination
	 *            destination to which resources will be copied
	 * @return IResource[] the resulting {@link IResource}[]
	 * @see WorkspaceModifyOperation
	 * @see Display#getThread()
	 * @see Thread#currentThread()
	 */
	public IResource[] copyResources(final IResource[] resources,
			IContainer destination) {
		return copyResources(resources, destination, true, null);
	}

	/**
	 * Copies the given resources to the destination in the current Thread
	 * without forking a new Thread or blocking using a
	 * WorkspaceModifyOperation. It recommended that this method only be called
	 * from a {@link WorkspaceJob} to avoid possible deadlock.
	 * 
	 * @param resources
	 *            the resources to copy
	 * @param destination
	 *            destination to which resources will be copied
	 * @param monitor
	 *            the monitor that information will be sent to.
	 * @return IResource[] the resulting {@link IResource}[]
	 * @see WorkspaceModifyOperation
	 * @see WorkspaceJob
     * @since 3.2
	 */
	public IResource[] copyResourcesInCurrentThread(final IResource[] resources,
			IContainer destination, IProgressMonitor monitor) {
		return copyResources(resources, destination, false, monitor);
	}

	/**
	 * Copies the given resources to the destination.
	 * 
	 * @param resources
	 *            the resources to copy
	 * @param destination
	 *            destination to which resources will be copied
	 * @return IResource[] the resulting {@link IResource}[]
	 */
	private IResource[] copyResources(final IResource[] resources,
			IContainer destination, boolean fork, IProgressMonitor monitor) {
		final IPath destinationPath = destination.getFullPath();
		final IResource[][] copiedResources = new IResource[1][0];

		// test resources for existence separate from validate API.
		// Validate is performance critical and resource exists
		// check is potentially slow. Fixes bugs 16129/28602.
		IStatus resourceStatus = checkExist(resources);
		if (resourceStatus.getSeverity() != IStatus.OK) {
			displayError(resourceStatus);
			return copiedResources[0];
		}
		String errorMsg = validateDestination(destination, resources);
		if (errorMsg != null) {
			displayError(errorMsg);
			return copiedResources[0];
		}

		if (fork) {
			WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
				public void execute(IProgressMonitor monitor) {
					copyResources(resources, destinationPath, copiedResources,
							monitor);
				}
			};

			try {
				PlatformUI.getWorkbench().getProgressService().run(true, true,
						op);
			} catch (InterruptedException e) {
				return copiedResources[0];
			} catch (InvocationTargetException e) {
				display(e);
			}
		}

		else
			copyResources(resources, destinationPath, copiedResources, monitor);

		// If errors occurred, open an Error dialog
		if (errorStatus != null) {
			displayError(errorStatus);
			errorStatus = null;
		}
		return copiedResources[0];
	}

	private void display(InvocationTargetException e) {
		// CoreExceptions are collected above, but unexpected runtime
		// exceptions and errors may still occur.
		IDEWorkbenchPlugin.getDefault().getLog().log(
				StatusUtil.newStatus(IStatus.ERROR, MessageFormat.format(
						"Exception in {0}.performCopy(): {1}", //$NON-NLS-1$
						new Object[] { getClass().getName(),
								e.getTargetException() }), null));
		displayError(NLS
				.bind(
						IDEWorkbenchMessages.CopyFilesAndFoldersOperation_internalError,
						e.getTargetException().getMessage()));
	}

	/**
	 * Copies the given URIS and folders to the destination. The current Thread
	 * is halted while the resources are copied using a
	 * WorkspaceModifyOperation. This method should be called from the UI
	 * Thread.
	 * 
	 * @param uris
	 *            the URIs to copy
	 * @param destination
	 *            destination to which files will be copied
	 * @see WorkspaceModifyOperation
	 * @see Display#getThread()
	 * @see Thread#currentThread()
	 * @since 3.2
	 */
	public void copyFiles(URI[] uris, IContainer destination) {
		IFileStore[] stores = buildFileStores(uris);
		if (stores == null)
			return;

		copyFileStores(destination, stores, true, null);
	}

	/**
	 * Copies the given files and folders to the destination without forking a
	 * new Thread or blocking using a WorkspaceModifyOperation. It is
	 * recommended that this method only be called from a {@link WorkspaceJob}
	 * to avoid possible deadlock.
	 * 
	 * @param uris
	 *            the URIs to copy
	 * @param destination
	 *            destination to which URIS will be copied
	 * @param monitor
	 *            the monitor that information will be sent to.
	 * @see WorkspaceModifyOperation
	 * @see WorkspaceJob
     * @since 3.2
	 */
	public void copyFilesInCurrentThread(URI[] uris, IContainer destination,
			IProgressMonitor monitor) {
		IFileStore[] stores = buildFileStores(uris);
		if (stores == null)
			return;

		copyFileStores(destination, stores, false, monitor);
	}

	/**
	 * Build the collection of fileStores that map to fileNames. If any of them
	 * cannot be found then match then return <code>null</code>.
	 * 
	 * @param uris
	 * @return IFileStore[]
	 */
	private IFileStore[] buildFileStores(URI[] uris) {
		IFileStore[] stores = new IFileStore[uris.length];
		for (int i = 0; i < uris.length; i++) {
			IFileStore store;
			try {
				store = EFS.getStore(uris[i]);
			} catch (CoreException e) {
				IDEWorkbenchPlugin.log(e.getMessage(), e);
				reportFileInfoNotFound(uris[i].toString());
				return null;
			}
			if (store == null) {
				reportFileInfoNotFound(uris[i].toString());
				return null;
			}
			stores[i] = store;
		}
		return stores;

	}

	/**
	 * Copies the given files and folders to the destination. The current Thread
	 * is halted while the resources are copied using a
	 * WorkspaceModifyOperation. This method should be called from the UI
	 * Thread.
	 * 
	 * @param fileNames
	 *            names of the files to copy
	 * @param destination
	 *            destination to which files will be copied
	 * @see WorkspaceModifyOperation
	 * @see Display#getThread()
	 * @see Thread#currentThread()
     * @since 3.2
	 */
	public void copyFiles(final String[] fileNames, IContainer destination) {
		IFileStore[] stores = buildFileStores(fileNames);
		if (stores == null)
			return;

		copyFileStores(destination, stores, true, null);
	}

	/**
	 * Copies the given files and folders to the destination without forking a
	 * new Thread or blocking using a WorkspaceModifyOperation. It is
	 * recommended that this method only be called from a {@link WorkspaceJob}
	 * to avoid possible deadlock.
	 * 
	 * @param fileNames
	 *            names of the files to copy
	 * @param destination
	 *            destination to which files will be copied
	 * @param monitor
	 *            the monitor that information will be sent to.
	 * @see WorkspaceModifyOperation
	 * @see WorkspaceJob
     * @since 3.2
	 */
	public void copyFilesInCurrentThread(final String[] fileNames, IContainer destination,
			IProgressMonitor monitor) {
		IFileStore[] stores = buildFileStores(fileNames);
		if (stores == null)
			return;

		copyFileStores(destination, stores, false, monitor);
	}

	/**
	 * Build the collection of fileStores that map to fileNames. If any of them
	 * cannot be found then match then return null.
	 * 
	 * @param fileNames
	 * @return IFileStore[]
	 */
	private IFileStore[] buildFileStores(final String[] fileNames) {
		IFileStore[] stores = new IFileStore[fileNames.length];
		for (int i = 0; i < fileNames.length; i++) {
			IFileStore store = IDEResourceInfoUtils.getFileStore(fileNames[i]);
			if (store == null) {
				reportFileInfoNotFound(fileNames[i]);
				return null;
			}
			stores[i] = store;
		}
		return stores;
	}

	/**
	 * Report that a file info could not be found.
	 * 
	 * @param fileName
	 */
	private void reportFileInfoNotFound(final String fileName) {

		messageShell.getDisplay().syncExec(new Runnable() {
			public void run() {
				ErrorDialog
						.openError(
								messageShell,
								getProblemsTitle(),
								NLS
										.bind(
												IDEWorkbenchMessages.CopyFilesAndFoldersOperation_infoNotFound,
												fileName), null);
			}
		});
	}

	/**
	 * Copies the given files and folders to the destination.
	 * 
	 * @param stores
	 *            the file stores to copy
	 * @param destination
	 *            destination to which files will be copied
	 */
	private void copyFileStores(IContainer destination,
			final IFileStore[] stores, boolean fork, IProgressMonitor monitor) {
		// test files for existence separate from validate API
		// because an external file may not exist until the copy actually
		// takes place (e.g., WinZip contents).
		IStatus fileStatus = checkExist(stores);
		if (fileStatus.getSeverity() != IStatus.OK) {
			displayError(fileStatus);
			return;
		}
		String errorMsg = validateImportDestinationInternal(destination, stores);
		if (errorMsg != null) {
			displayError(errorMsg);
			return;
		}
		final IPath destinationPath = destination.getFullPath();

		if (fork) {
			WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
				public void execute(IProgressMonitor monitor) {
					copyFileStores(stores, destinationPath, monitor);
				}
			};
			try {
				PlatformUI.getWorkbench().getProgressService().run(true, true,
						op);
			} catch (InterruptedException e) {
				return;
			} catch (InvocationTargetException exception) {
				display(exception);
			}
		} else
			copyFileStores(stores, destinationPath, monitor);

		// If errors occurred, open an Error dialog
		if (errorStatus != null) {
			displayError(errorStatus);
			errorStatus = null;
		}
	}

	/**
	 * Display the supplied status in an error dialog.
	 * 
	 * @param fileStatus
	 */
	private void displayError(final IStatus status) {
		messageShell.getDisplay().syncExec(new Runnable() {
			public void run() {
				ErrorDialog.openError(messageShell, getProblemsTitle(), null,
						status);
			}
		});
	}

	/**
	 * Creates a file or folder handle for the source resource as if it were to
	 * be created in the destination container.
	 * 
	 * @param destination
	 *            destination container
	 * @param source
	 *            source resource
	 * @return IResource file or folder handle, depending on the source type.
	 */
	IResource createLinkedResourceHandle(IContainer destination,
			IResource source) {
		IWorkspace workspace = destination.getWorkspace();
		IWorkspaceRoot workspaceRoot = workspace.getRoot();
		IPath linkPath = destination.getFullPath().append(source.getName());
		IResource linkHandle;

		if (source.getType() == IResource.FOLDER) {
			linkHandle = workspaceRoot.getFolder(linkPath);
		} else {
			linkHandle = workspaceRoot.getFile(linkPath);
		}
		return linkHandle;
	}

	/**
	 * Removes the given resource from the workspace.
	 * 
	 * @param resource
	 *            resource to remove from the workspace
	 * @param monitor
	 *            a progress monitor for showing progress and for cancelation
	 * @return true the resource was deleted successfully false the resource was
	 *         not deleted because a CoreException occurred
	 */
	boolean delete(IResource resource, IProgressMonitor monitor) {
		boolean force = false; // don't force deletion of out-of-sync resources

		if (resource.getType() == IResource.PROJECT) {
			// if it's a project, ask whether content should be deleted too
			IProject project = (IProject) resource;
			try {
				project.delete(true, force, monitor);
			} catch (CoreException e) {
				recordError(e); // log error
				return false;
			}
		} else {
			// if it's not a project, just delete it
			int flags = IResource.KEEP_HISTORY;
			if (force) {
				flags = flags | IResource.FORCE;
			}
			try {
				resource.delete(flags, monitor);
			} catch (CoreException e) {
				recordError(e); // log error
				return false;
			}
		}
		return true;
	}

	/**
	 * Opens an error dialog to display the given message.
	 * 
	 * @param message
	 *            the error message to show
	 */
	private void displayError(final String message) {
		messageShell.getDisplay().syncExec(new Runnable() {
			public void run() {
				MessageDialog.openError(messageShell, getProblemsTitle(),
						message);
			}
		});
	}

	/**
	 * Returns the resource either casted to or adapted to an IFile.
	 * 
	 * @param resource
	 *            resource to cast/adapt
	 * @return the resource either casted to or adapted to an IFile.
	 *         <code>null</code> if the resource does not adapt to IFile
	 */
	protected IFile getFile(IResource resource) {
		if (resource instanceof IFile) {
			return (IFile) resource;
		}
		return (IFile) ((IAdaptable) resource).getAdapter(IFile.class);
	}

	/**
	 * Returns java.io.File objects for the given file names.
	 * 
	 * @param fileNames
	 *            files to return File object for.
	 * @return java.io.File objects for the given file names.
	 * @deprecated This method is not longer in use anywhere in this class and
	 *             is only provided for backwards compatability with subclasses
	 *             of the receiver.
	 */
	protected File[] getFiles(String[] fileNames) {
		File[] files = new File[fileNames.length];

		for (int i = 0; i < fileNames.length; i++) {
			files[i] = new File(fileNames[i]);
		}
		return files;
	}

	/**
	 * Returns the resource either casted to or adapted to an IFolder.
	 * 
	 * @param resource
	 *            resource to cast/adapt
	 * @return the resource either casted to or adapted to an IFolder.
	 *         <code>null</code> if the resource does not adapt to IFolder
	 */
	protected IFolder getFolder(IResource resource) {
		if (resource instanceof IFolder) {
			return (IFolder) resource;
		}
		return (IFolder) ((IAdaptable) resource).getAdapter(IFolder.class);
	}

	/**
	 * Returns a new name for a copy of the resource at the given path in the
	 * given workspace.
	 * 
	 * @param originalName
	 *            the full path of the resource
	 * @param workspace
	 *            the workspace
	 * @return the new full path for the copy, or <code>null</code> if the
	 *         resource should not be copied
	 */
	private IPath getNewNameFor(final IPath originalName,
			final IWorkspace workspace) {
		final IResource resource = workspace.getRoot().findMember(originalName);
		final IPath prefix = resource.getFullPath().removeLastSegments(1);
		final String returnValue[] = { "" }; //$NON-NLS-1$

		messageShell.getDisplay().syncExec(new Runnable() {
			public void run() {
				IInputValidator validator = new IInputValidator() {
					public String isValid(String string) {
						if (resource.getName().equals(string)) {
							return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_nameMustBeDifferent;
						}
						IStatus status = workspace.validateName(string,
								resource.getType());
						if (!status.isOK()) {
							return status.getMessage();
						}
						if (workspace.getRoot().exists(prefix.append(string))) {
							return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_nameExists;
						}
						return null;
					}
				};

				InputDialog dialog = new InputDialog(
						messageShell,
						IDEWorkbenchMessages.CopyFilesAndFoldersOperation_inputDialogTitle,
						NLS
								.bind(
										IDEWorkbenchMessages.CopyFilesAndFoldersOperation_inputDialogMessage,
										resource.getName()), getAutoNewNameFor(
								originalName, workspace).lastSegment()
								.toString(), validator);
				dialog.setBlockOnOpen(true);
				dialog.open();
				if (dialog.getReturnCode() == Window.CANCEL) {
					returnValue[0] = null;
				} else {
					returnValue[0] = dialog.getValue();
				}
			}
		});
		if (returnValue[0] == null) {
			throw new OperationCanceledException();
		}
		return prefix.append(returnValue[0]);
	}

	/**
	 * Returns the task title for this operation's progress dialog.
	 * 
	 * @return the task title
	 */
	protected String getOperationTitle() {
		return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_operationTitle;
	}

	/**
	 * Returns the message for this operation's problems dialog.
	 * 
	 * @return the problems message
	 */
	protected String getProblemsMessage() {
		return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_problemMessage;
	}

	/**
	 * Returns the title for this operation's problems dialog.
	 * 
	 * @return the problems dialog title
	 */
	protected String getProblemsTitle() {
		return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_copyFailedTitle;
	}

	/**
	 * Returns whether the source file in a destination collision will be
	 * validateEdited together with the collision itself. Returns false. Should
	 * return true if the source file is to be deleted after the operation.
	 * 
	 * @return boolean <code>true</code> if the source file in a destination
	 *         collision should be validateEdited. <code>false</code> if only
	 *         the destination should be validated.
	 */
	protected boolean getValidateConflictSource() {
		return false;
	}

	/**
	 * Returns whether the given resources are either both linked or both
	 * unlinked.
	 * 
	 * @param source
	 *            source resource
	 * @param destination
	 *            destination resource
	 * @return boolean <code>true</code> if both resources are either linked
	 *         or unlinked. <code>false</code> otherwise.
	 */
	protected boolean homogenousResources(IResource source,
			IResource destination) {
		boolean isSourceLinked = source.isLinked();
		boolean isDestinationLinked = destination.isLinked();

		return (isSourceLinked && isDestinationLinked || isSourceLinked == false
				&& isDestinationLinked == false);
	}

	/**
	 * Returns whether the given resource is accessible. Files and folders are
	 * always considered accessible and a project is accessible if it is open.
	 * 
	 * @param resource
	 *            the resource
	 * @return <code>true</code> if the resource is accessible, and
	 *         <code>false</code> if it is not
	 */
	private boolean isAccessible(IResource resource) {
		switch (resource.getType()) {
		case IResource.FILE:
			return true;
		case IResource.FOLDER:
			return true;
		case IResource.PROJECT:
			return ((IProject) resource).isOpen();
		default:
			return false;
		}
	}

	/**
	 * Returns whether any of the given source resources are being recopied to
	 * their current container.
	 * 
	 * @param sourceResources
	 *            the source resources
	 * @param destination
	 *            the destination container
	 * @return <code>true</code> if at least one of the given source
	 *         resource's parent container is the same as the destination
	 */
	boolean isDestinationSameAsSource(IResource[] sourceResources,
			IContainer destination) {
		IPath destinationLocation = destination.getLocation();

		for (int i = 0; i < sourceResources.length; i++) {
			IResource sourceResource = sourceResources[i];
			if (sourceResource.getParent().equals(destination)) {
				return true;
			} else if (destinationLocation != null) {
				// do thorough check to catch linked resources. Fixes bug 29913.
				IPath sourceLocation = sourceResource.getLocation();
				IPath destinationResource = destinationLocation
						.append(sourceResource.getName());
				if (sourceLocation != null
						&& sourceLocation.isPrefixOf(destinationResource)) {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * Copies the given resources to the destination container with the given
	 * name.
	 * <p>
	 * Note: the destination container may need to be created prior to copying
	 * the resources.
	 * </p>
	 * 
	 * @param resources
	 *            the resources to copy
	 * @param destination
	 *            the path of the destination container
	 * @param monitor
	 *            a progress monitor for showing progress and for cancelation
	 * @return <code>true</code> if the copy operation completed without
	 *         errors
	 */
	private boolean performCopy(IResource[] resources, IPath destination,
			IProgressMonitor monitor) {
		try {
			ContainerGenerator generator = new ContainerGenerator(destination);
			generator.generateContainer(new SubProgressMonitor(monitor, 10));
			IProgressMonitor subMonitor = new SubProgressMonitor(monitor, 75);
			copy(resources, destination, subMonitor);
		} catch (CoreException e) {
			recordError(e); // log error
			return false;
		} finally {
			monitor.done();
		}
		return true;
	}

	/**
	 * Individually copies the given resources to the specified destination
	 * container checking for name collisions. If a collision is detected, it is
	 * saved with a new name.
	 * <p>
	 * Note: the destination container may need to be created prior to copying
	 * the resources.
	 * </p>
	 * 
	 * @param resources
	 *            the resources to copy
	 * @param destination
	 *            the path of the destination container
	 * @return <code>true</code> if the copy operation completed without
	 *         errors.
	 */
	private boolean performCopyWithAutoRename(IResource[] resources,
			IPath destination, IProgressMonitor monitor) {
		IWorkspace workspace = resources[0].getWorkspace();

		try {
			ContainerGenerator generator = new ContainerGenerator(destination);
			generator.generateContainer(new SubProgressMonitor(monitor, 10));

			IProgressMonitor subMonitor = new SubProgressMonitor(monitor, 75);
			subMonitor.beginTask(getOperationTitle(), resources.length);

			for (int i = 0; i < resources.length; i++) {
				IResource source = resources[i];
				IPath destinationPath = destination.append(source.getName());

				if (workspace.getRoot().exists(destinationPath)) {
					destinationPath = getNewNameFor(destinationPath, workspace);
				}
				if (destinationPath != null) {
					try {
						source.copy(destinationPath, IResource.SHALLOW,
								new SubProgressMonitor(subMonitor, 0));
					} catch (CoreException e) {
						recordError(e); // log error
						return false;
					}
				}
				subMonitor.worked(1);
				if (subMonitor.isCanceled()) {
					throw new OperationCanceledException();
				}
			}
		} catch (CoreException e) {
			recordError(e); // log error
			return false;
		} finally {
			monitor.done();
		}

		return true;
	}

	/**
	 * Performs an import of the given stores into the provided container.
	 * Returns a status indicating if the import was successful.
	 * 
	 * @param stores
	 *            stores that are to be imported
	 * @param target
	 *            container to which the import will be done
	 * @param monitor
	 *            a progress monitor for showing progress and for cancelation
	 */
	private void performFileImport(IFileStore[] stores, IContainer target,
			IProgressMonitor monitor) {
		IOverwriteQuery query = new IOverwriteQuery() {
			public String queryOverwrite(String pathString) {
				if (alwaysOverwrite)
					return ALL;

				final String returnCode[] = { CANCEL };
				final String msg = NLS
						.bind(
								IDEWorkbenchMessages.CopyFilesAndFoldersOperation_overwriteQuestion,
								pathString);
				final String[] options = { IDialogConstants.YES_LABEL,
						IDialogConstants.YES_TO_ALL_LABEL,
						IDialogConstants.NO_LABEL,
						IDialogConstants.CANCEL_LABEL };
				messageShell.getDisplay().syncExec(new Runnable() {
					public void run() {
						MessageDialog dialog = new MessageDialog(
								messageShell,
								IDEWorkbenchMessages.CopyFilesAndFoldersOperation_question,
								null, msg, MessageDialog.QUESTION, options, 0);
						dialog.open();
						int returnVal = dialog.getReturnCode();
						String[] returnCodes = { YES, ALL, NO, CANCEL };
						returnCode[0] = returnVal == -1 ? CANCEL
								: returnCodes[returnVal];
					}
				});
				if (returnCode[0] == ALL) {
					alwaysOverwrite = true;
				} else if (returnCode[0] == CANCEL) {
					canceled = true;
				}
				return returnCode[0];
			}
		};

		ImportOperation op = new ImportOperation(target.getFullPath(),
				stores[0].getParent(), FileStoreStructureProvider.INSTANCE,
				query, Arrays.asList(stores));
		op.setContext(messageShell);
		op.setCreateContainerStructure(false);
		try {
			op.run(monitor);
		} catch (InterruptedException e) {
			return;
		} catch (InvocationTargetException e) {
			if (e.getTargetException() instanceof CoreException) {
				displayError(((CoreException) e.getTargetException())
						.getStatus());
			} else {
				display(e);
			}
			return;
		}
		// Special case since ImportOperation doesn't throw a CoreException on
		// failure.
		IStatus status = op.getStatus();
		if (!status.isOK()) {
			if (errorStatus == null)
				errorStatus = new MultiStatus(PlatformUI.PLUGIN_ID,
						IStatus.ERROR, getProblemsMessage(), null);
			errorStatus.merge(status);
		}
	}

	/**
	 * Records the core exception to be displayed to the user once the action is
	 * finished.
	 * 
	 * @param error
	 *            a <code>CoreException</code>
	 */
	private void recordError(CoreException error) {
		if (errorStatus == null)
			errorStatus = new MultiStatus(PlatformUI.PLUGIN_ID, IStatus.ERROR,
					getProblemsMessage(), error);

		errorStatus.merge(error.getStatus());
	}

	/**
	 * Checks whether the destination is valid for copying the source resources.
	 * <p>
	 * Note this method is for internal use only. It is not API.
	 * </p>
	 * 
	 * @param destination
	 *            the destination container
	 * @param sourceResources
	 *            the source resources
	 * @return an error message, or <code>null</code> if the path is valid
	 */
	public String validateDestination(IContainer destination,
			IResource[] sourceResources) {
		if (!isAccessible(destination)) {
			return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_destinationAccessError;
		}
		String destinationMessage = validateDestinationLocation(destination);
		if (destinationMessage != null) {
			return destinationMessage;
		}
		IContainer firstParent = null;
		IPath destinationLocation = destination.getLocation();
		for (int i = 0; i < sourceResources.length; i++) {
			IResource sourceResource = sourceResources[i];
			if (firstParent == null) {
				firstParent = sourceResource.getParent();
			} else if (firstParent.equals(sourceResource.getParent()) == false) {
				// Resources must have common parent. Fixes bug 33398.
				return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_parentNotEqual;
			}

			IPath sourceLocation = sourceResource.getLocation();
			if (sourceLocation == null) {
				if (sourceResource.isLinked()) {
					// Don't allow copying linked resources with undefined path
					// variables. See bug 28754.
					return NLS
							.bind(
									IDEWorkbenchMessages.CopyFilesAndFoldersOperation_missingPathVariable,
									sourceResource.getName());
				}
				return NLS
						.bind(
								IDEWorkbenchMessages.CopyFilesAndFoldersOperation_resourceDeleted,
								sourceResource.getName());

			}
			if (sourceLocation.equals(destinationLocation)) {
				return NLS
						.bind(
								IDEWorkbenchMessages.CopyFilesAndFoldersOperation_sameSourceAndDest,
								sourceResource.getName());
			}
			// is the source a parent of the destination?
			if (sourceLocation.isPrefixOf(destinationLocation)) {
				return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_destinationDescendentError;
			}

			String linkedResourceMessage = validateLinkedResource(destination,
					sourceResource);
			if (linkedResourceMessage != null) {
				return linkedResourceMessage;
			}
		}
		return null;
	}

	/**
	 * Validates whether the destination location exists. Linked resources
	 * created on undefined path variables have an undefined location.
	 * 
	 * @param destination
	 *            destination container
	 * @return error message or null if destination location is valid (non-<code>null</code>)
	 */
	private String validateDestinationLocation(IContainer destination) {
		IPath destinationLocation = destination.getLocation();

		if (destinationLocation == null) {
			if (destination.isLinked()) {
				return NLS
						.bind(
								IDEWorkbenchMessages.CopyFilesAndFoldersOperation_missingPathVariable,
								destination.getName());
			}
			return NLS
					.bind(
							IDEWorkbenchMessages.CopyFilesAndFoldersOperation_resourceDeleted,
							destination.getName());

		}
		return null;
	}

	/**
	 * Validates that the given source resources can be copied to the
	 * destination as decided by the VCM provider.
	 * 
	 * @param destination
	 *            copy destination
	 * @param sourceResources
	 *            source resources
	 * @return <code>true</code> all files passed validation or there were no
	 *         files to validate. <code>false</code> one or more files did not
	 *         pass validation.
	 */
	private boolean validateEdit(IContainer destination,
			IResource[] sourceResources) {
		ArrayList copyFiles = new ArrayList();

		collectExistingReadonlyFiles(destination.getFullPath(),
				sourceResources, copyFiles);
		if (copyFiles.size() > 0) {
			IFile[] files = (IFile[]) copyFiles.toArray(new IFile[copyFiles
					.size()]);
			IWorkspace workspace = ResourcesPlugin.getWorkspace();
			IStatus status = workspace.validateEdit(files, messageShell);

			canceled = status.isOK() == false;
			return status.isOK();
		}
		return true;
	}

	/**
	 * Checks whether the destination is valid for copying the source files.
	 * <p>
	 * Note this method is for internal use only. It is not API.
	 * </p>
	 * 
	 * @param destination
	 *            the destination container
	 * @param sourceNames
	 *            the source file names
	 * @return an error message, or <code>null</code> if the path is valid
	 */
	public String validateImportDestination(IContainer destination,
			String[] sourceNames) {

		IFileStore[] stores = new IFileStore[sourceNames.length];
		for (int i = 0; i < sourceNames.length; i++) {
			IFileStore store = IDEResourceInfoUtils
					.getFileStore(sourceNames[i]);
			if (store == null)
				return NLS
						.bind(
								IDEWorkbenchMessages.CopyFilesAndFoldersOperation_infoNotFound,
								sourceNames[i]);
			stores[i] = store;
		}
		return validateImportDestinationInternal(destination, stores);

	}

	/**
	 * Checks whether the destination is valid for copying the source file
	 * stores.
	 * <p>
	 * Note this method is for internal use only. It is not API.
	 * </p>
	 * <p>
	 * TODO Bug 117804. This method has been renamed to avoid a bug in the
	 * Eclipse compiler with regards to visibility and type resolution when
	 * linking.
	 * </p>
	 * 
	 * @param destination
	 *            the destination container
	 * @param sourceStores
	 *            the source IFileStore
	 * @return an error message, or <code>null</code> if the path is valid
	 */
	private String validateImportDestinationInternal(IContainer destination,
			IFileStore[] sourceStores) {
		if (!isAccessible(destination)) {
			return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_destinationAccessError;
		}
		String destinationMessage = validateDestinationLocation(destination);
		if (destinationMessage != null) {
			return destinationMessage;
		}

		IFileStore destinationStore;
		try {
			destinationStore = EFS.getStore(destination.getLocationURI());
		} catch (CoreException exception) {
			IDEWorkbenchPlugin.log(exception.getLocalizedMessage(), exception);
			return NLS
					.bind(
							IDEWorkbenchMessages.CopyFilesAndFoldersOperation_internalError,
							exception.getLocalizedMessage());
		}
		for (int i = 0; i < sourceStores.length; i++) {
			IFileStore sourceStore = sourceStores[i];
			IFileStore sourceParentStore = sourceStore.getParent();

			if (sourceStore != null) {
				if (destinationStore.equals(sourceStore)
						|| (sourceParentStore != null && destinationStore
								.equals(sourceParentStore))) {
					return NLS
							.bind(
									IDEWorkbenchMessages.CopyFilesAndFoldersOperation_importSameSourceAndDest,
									sourceStore.getName());
				}
				// work around bug 16202. replacement for
				// sourcePath.isPrefixOf(destinationPath)
				IFileStore destinationParent = destinationStore.getParent();
				if (sourceStore.isParentOf(destinationParent))
					return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_destinationDescendentError;

			}
		}
		return null;
	}

	/**
	 * Check if the destination is valid for the given source resource.
	 * 
	 * @param destination
	 *            destination container of the operation
	 * @param source
	 *            source resource
	 * @return String error message or null if the destination is valid
	 */
	private String validateLinkedResource(IContainer destination,
			IResource source) {
		if (source.isLinked() == false) {
			return null;
		}
		IWorkspace workspace = destination.getWorkspace();
		IResource linkHandle = createLinkedResourceHandle(destination, source);
		IStatus locationStatus = workspace.validateLinkLocation(linkHandle,
				source.getRawLocation());

		if (locationStatus.getSeverity() == IStatus.ERROR) {
			return locationStatus.getMessage();
		}
		IPath sourceLocation = source.getLocation();
		if (source.getProject().equals(destination.getProject()) == false
				&& source.getType() == IResource.FOLDER
				&& sourceLocation != null) {
			// prevent merging linked folders that point to the same
			// file system folder
			try {
				IResource[] members = destination.members();
				for (int j = 0; j < members.length; j++) {
					if (sourceLocation.equals(members[j].getLocation())
							&& source.getName().equals(members[j].getName())) {
						return NLS
								.bind(
										IDEWorkbenchMessages.CopyFilesAndFoldersOperation_sameSourceAndDest,
										source.getName());
					}
				}
			} catch (CoreException exception) {
				displayError(NLS
						.bind(
								IDEWorkbenchMessages.CopyFilesAndFoldersOperation_internalError,
								exception.getMessage()));
			}
		}
		return null;
	}

	/**
	 * Returns whether moving all of the given source resources to the given
	 * destination container could be done without causing name collisions.
	 * 
	 * @param destination
	 *            the destination container
	 * @param sourceResources
	 *            the list of resources
	 * @return <code>true</code> if there would be no name collisions, and
	 *         <code>false</code> if there would
	 */
	private IResource[] validateNoNameCollisions(IContainer destination,
			IResource[] sourceResources) {
		List copyItems = new ArrayList();
		IWorkspaceRoot workspaceRoot = destination.getWorkspace().getRoot();
		int overwrite = IDialogConstants.NO_ID;

		// Check to see if we would be overwriting a parent folder.
		// Cancel entire copy operation if we do.
		for (int i = 0; i < sourceResources.length; i++) {
			final IResource sourceResource = sourceResources[i];
			final IPath destinationPath = destination.getFullPath().append(
					sourceResource.getName());
			final IPath sourcePath = sourceResource.getFullPath();

			IResource newResource = workspaceRoot.findMember(destinationPath);
			if (newResource != null && destinationPath.isPrefixOf(sourcePath)) {
				displayError(NLS
						.bind(
								IDEWorkbenchMessages.CopyFilesAndFoldersOperation_overwriteProblem,
								destinationPath, sourcePath));

				canceled = true;
				return null;
			}
		}
		// Check for overwrite conflicts
		for (int i = 0; i < sourceResources.length; i++) {
			final IResource source = sourceResources[i];
			final IPath destinationPath = destination.getFullPath().append(
					source.getName());

			IResource newResource = workspaceRoot.findMember(destinationPath);
			if (newResource != null) {
				if (overwrite != IDialogConstants.YES_TO_ALL_ID
						|| (newResource.getType() == IResource.FOLDER && homogenousResources(
								source, destination) == false)) {
					overwrite = checkOverwrite(source, newResource);
				}
				if (overwrite == IDialogConstants.YES_ID
						|| overwrite == IDialogConstants.YES_TO_ALL_ID) {
					copyItems.add(source);
				} else if (overwrite == IDialogConstants.CANCEL_ID) {
					canceled = true;
					return null;
				}
			} else {
				copyItems.add(source);
			}
		}
		return (IResource[]) copyItems.toArray(new IResource[copyItems.size()]);
	}

	private void copyResources(final IResource[] resources,
			final IPath destinationPath, final IResource[][] copiedResources,
			IProgressMonitor monitor) {
		IResource[] copyResources = resources;

		// Fix for bug 31116. Do not provide a task name when
		// creating the task.
		monitor.beginTask("", 100); //$NON-NLS-1$
		monitor.setTaskName(getOperationTitle());
		monitor.worked(10); // show some initial progress

		// Checks only required if this is an exisiting container path.
		boolean copyWithAutoRename = false;
		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
		if (root.exists(destinationPath)) {
			IContainer container = (IContainer) root
					.findMember(destinationPath);
			// If we're copying to the source container then perform
			// auto-renames on all resources to avoid name collisions.
			if (isDestinationSameAsSource(copyResources, container)
					&& canPerformAutoRename()) {
				copyWithAutoRename = true;
			} else {
				// If no auto-renaming will be happening, check for
				// potential name collisions at the target resource
				copyResources = validateNoNameCollisions(container,
						copyResources);
				if (copyResources == null) {
					if (canceled)
						return;
					displayError(IDEWorkbenchMessages.CopyFilesAndFoldersOperation_nameCollision);
					return;
				}
				if (validateEdit(container, copyResources) == false)
					return;
			}
		}

		errorStatus = null;
		if (copyResources.length > 0) {
			if (copyWithAutoRename)
				performCopyWithAutoRename(copyResources, destinationPath,
						monitor);
			else
				performCopy(copyResources, destinationPath, monitor);
		}
		copiedResources[0] = copyResources;
	}

	private void copyFileStores(final IFileStore[] stores,
			final IPath destinationPath, IProgressMonitor monitor) {
		// Checks only required if this is an exisiting container path.
		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
		if (root.exists(destinationPath)) {
			IContainer container = (IContainer) root
					.findMember(destinationPath);

			performFileImport(stores, container, monitor);
		}
	}
}
