/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-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.text.MessageFormat;
import java.util.*;

import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.jface.dialogs.*;
import org.eclipse.jface.window.Window;
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.StatusUtil;
import org.eclipse.ui.wizards.datatransfer.FileSystemStructureProvider;
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 parentShell;

	/**
	 * 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 = IDEWorkbenchMessages.format("CopyFilesAndFoldersOperation.copyNameTwoArgs", new Object[] { new Integer(counter), resourceName }); //$NON-NLS-1$
			else
				nameSegment = IDEWorkbenchMessages.format("CopyFilesAndFoldersOperation.copyNameOneArg", new Object[] { resourceName }); //$NON-NLS-1$

			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) {
		parentShell = 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 IDEWorkbenchMessages.format(
			"CopyFilesAndFoldersOperation.deepCopyQuestion", //$NON-NLS-1$
			new Object[] {source.getFullPath().makeRelative()});
	}
	/**
	 * Checks whether the files with the given names exist. 
	 *
	 * @param names path to the file. must not be null.
	 * 	If the path is not valid it will not be tested. 
	 * @return Multi status with one error message for each missing file.
	 */
	IStatus checkExist(String[] names) {
		MultiStatus multiStatus = new MultiStatus(
			PlatformUI.PLUGIN_ID, 
			IStatus.OK,
			getProblemsMessage(),
			null);
			 		
		for (int i = 0; i < names.length; i++) {
			IPath path = new Path(names[i]);
			File file = path.toFile();
			
			if (file != null && file.exists() == false) {
				String message = IDEWorkbenchMessages.format(
					"CopyFilesAndFoldersOperation.resourceDeleted",	//$NON-NLS-1$
					new Object[] {file.getName()});				
				IStatus status = new Status(
					IStatus.ERROR, 
					PlatformUI.PLUGIN_ID, 
					IStatus.OK, 
					message, 
					null);
				multiStatus.add(status);
			}
		}
		return multiStatus;
	}
	/**
	 * Checks whether the files with the given names exist. 
	 *
	 * @param names path to the file. must not be null.
	 * 	If the path is not valid it will not be tested. 
	 * @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) {
				IPath location = resource.getLocation();
				String message = null; 
				if (location != null) {
					File file = location.toFile();
					if (file.exists() == false) {
						if (resource.isLinked()) {
							message = IDEWorkbenchMessages.format(
								"CopyFilesAndFoldersOperation.missingLinkTarget", 	//$NON-NLS-1$
								new Object[] {resource.getName()});
						} else {
							message = IDEWorkbenchMessages.format(
								"CopyFilesAndFoldersOperation.resourceDeleted",	//$NON-NLS-1$
								new Object[] {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 shell the shell to create the overwrite prompt dialog in 
	 * @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 Shell shell, 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 = IDEWorkbenchMessages.format(
							"CopyFilesAndFoldersOperation.overwriteMergeQuestion", //$NON-NLS-1$
							new Object[] { destination.getFullPath().makeRelative()});
					} else {
						if (destination.isLinked()) {
							message = IDEWorkbenchMessages.format(
								"CopyFilesAndFoldersOperation.overwriteNoMergeLinkQuestion", //$NON-NLS-1$
								new Object[] { destination.getFullPath().makeRelative()});
						}
						else {
							message = IDEWorkbenchMessages.format(
								"CopyFilesAndFoldersOperation.overwriteNoMergeNoLinkQuestion", //$NON-NLS-1$
								new Object[] { 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 {
					message = IDEWorkbenchMessages.format(
						"CopyFilesAndFoldersOperation.overwriteQuestion", //$NON-NLS-1$
						new Object[] { destination.getFullPath().makeRelative()});
				}
				MessageDialog dialog = new MessageDialog(
					shell, 
					IDEWorkbenchMessages.getString("CopyFilesAndFoldersOperation.resourceExists"), //$NON-NLS-1$
					null,
					message,
					MessageDialog.QUESTION,
					labels,
					0);
				dialog.open();
				result[0] = resultId[dialog.getReturnCode()];
			}
		};
		shell.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 {
		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, subMonitor);
				}
				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, 0));					
				}
			} else {
				if (existing != null) {
					if (homogenousResources(source, existing))			
						copyExisting(source, existing, subMonitor);
					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, 0));
					}						
				} else {
					source.copy(destinationPath, IResource.SHALLOW, new SubProgressMonitor(subMonitor, 0));
				}
				subMonitor.worked(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. 
	 * 
	 * @param resources the resources to copy
	 * @param destination destination to which resources will be copied
	 */
	public IResource[] copyResources(final IResource[] resources, IContainer destination) {
		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) {
			ErrorDialog.openError(
				parentShell, 
				getProblemsTitle(),
				null, // no special message
				resourceStatus);
			return copiedResources[0];
		}
		String errorMsg = validateDestination(destination, resources);
		if (errorMsg != null) {
			displayError(errorMsg);
			return copiedResources[0];
		}

		WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
			public void execute(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, monitor);
						if (copyResources == null) {
							if (canceled)
								return;
							displayError(IDEWorkbenchMessages.getString("CopyFilesAndFoldersOperation.nameCollision")); //$NON-NLS-1$
							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;
			}
		};

		try {
			new ProgressMonitorDialog(parentShell).run(true, true, op);
		} catch (InterruptedException e) {
			return copiedResources[0];
		} catch (InvocationTargetException e) {
			// CoreExceptions are collected above, but unexpected runtime exceptions and errors may still occur.
			Platform.getPlugin(PlatformUI.PLUGIN_ID).getLog().log(StatusUtil.newStatus(
					IStatus.ERROR, 
					MessageFormat.format(
						"Exception in {0}.performCopy(): {1}", //$NON-NLS-1$
						new Object[] {getClass().getName(), e.getTargetException()}), 
					null));
			displayError(IDEWorkbenchMessages.format(
				"CopyFilesAndFoldersOperation.internalError", //$NON-NLS-1$
				new Object[] { e.getTargetException().getMessage()}));
		}

		// If errors occurred, open an Error dialog
		if (errorStatus != null) {
			ErrorDialog.openError(
				parentShell, 
				getProblemsTitle(), 
				null, // no special message
				errorStatus);
			errorStatus = null;
		}
		return copiedResources[0];
	}
	/**
	 * Copies the given files and folders to the destination. 
	 * 
	 * @param fileNames names of the files to copy
	 * @param destination destination to which files will be copied
	 */
	public void copyFiles(final String[] fileNames, IContainer destination) {
		alwaysOverwrite = false;

		// 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(fileNames);
		if (fileStatus.getSeverity() != IStatus.OK) {
			ErrorDialog.openError(
				parentShell, 
				getProblemsTitle(),
				null, // no special message
				fileStatus);
			return;
		}
		String errorMsg = validateImportDestination(destination, fileNames);
		if (errorMsg != null) {
			displayError(errorMsg);
			return;
		}
		final IPath destinationPath = destination.getFullPath();

		WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
			public void execute(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(getFiles(fileNames), container, monitor);
				}
			}
		};
		try {
			new ProgressMonitorDialog(parentShell).run(true, true, op);
		} catch (InterruptedException e) {
			return;
		} catch (InvocationTargetException e) {
			// CoreExceptions are collected above, but unexpected runtime exceptions and errors may still occur.
			Platform.getPlugin(PlatformUI.PLUGIN_ID).getLog().log(StatusUtil.newStatus(IStatus.ERROR, MessageFormat.format("Exception in {0}.performCopy(): {1}", //$NON-NLS-1$
			new Object[] { getClass().getName(), e.getTargetException()}), null));
			displayError(IDEWorkbenchMessages.format("CopyFilesAndFoldersOperation.internalError", new Object[] { e.getTargetException().getMessage()})); //$NON-NLS-1$
		}

		// If errors occurred, open an Error dialog
		if (errorStatus != null) {
			ErrorDialog.openError(parentShell, getProblemsTitle(), //$NON-NLS-1$
			null, // no special message
			errorStatus);
			errorStatus = null;
		}
	}
	/**
	 * 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) throws CoreException {
		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) {
		parentShell.getDisplay().syncExec(new Runnable() {
			public void run() {
				MessageDialog.openError(parentShell, 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;
		}
		if (resource instanceof IAdaptable) {
			return (IFile) ((IAdaptable) resource).getAdapter(IFile.class);
		}
		return null;
	}
	/**
	 * 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.
	 */
	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;
		}
		if (resource instanceof IAdaptable) {
			return (IFolder) ((IAdaptable) resource).getAdapter(IFolder.class);
		}
		return null;
	}
	/**
	 * 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$

		parentShell.getDisplay().syncExec(new Runnable() {
			public void run() {
				IInputValidator validator = new IInputValidator() {
					public String isValid(String string) {
						if (resource.getName().equals(string)) {
							return IDEWorkbenchMessages.getString("CopyFilesAndFoldersOperation.nameMustBeDifferent"); //$NON-NLS-1$
						}
						IStatus status = workspace.validateName(string, resource.getType());
						if (!status.isOK()) {
							return status.getMessage();
						}
						if (workspace.getRoot().exists(prefix.append(string))) {
							return IDEWorkbenchMessages.getString("CopyFilesAndFoldersOperation.nameExists"); //$NON-NLS-1$
						}
						return null;
					}
				};

				InputDialog dialog = new InputDialog(parentShell, IDEWorkbenchMessages.getString("CopyFilesAndFoldersOperation.inputDialogTitle"), //$NON-NLS-1$
				IDEWorkbenchMessages.format("CopyFilesAndFoldersOperation.inputDialogMessage", new String[] { resource.getName()}), //$NON-NLS-1$
				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.getString("CopyFilesAndFoldersOperation.operationTitle"); //$NON-NLS-1$
	}
	/**
	 * Returns the message for this operation's problems dialog.
	 *
	 * @return the problems message
	 */
	protected String getProblemsMessage() {
		return IDEWorkbenchMessages.getString("CopyFilesAndFoldersOperation.problemMessage"); //$NON-NLS-1$
	}
	/**
	 * Returns the title for this operation's problems dialog.
	 *
	 * @return the problems dialog title
	 */
	protected String getProblemsTitle() {
		return IDEWorkbenchMessages.getString("CopyFilesAndFoldersOperation.copyFailedTitle"); //$NON-NLS-1$
	}
	/**
	 * 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 files into the provided container.
	 * Returns a status indicating if the import was successful.
	 * 
	 * @param files files 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(File[] files, IContainer target, IProgressMonitor monitor) {
		IOverwriteQuery query = new IOverwriteQuery() {
			public String queryOverwrite(String pathString) {
				if (alwaysOverwrite)
					return ALL;

				final String returnCode[] = { CANCEL };
				final String msg = IDEWorkbenchMessages.format("CopyFilesAndFoldersOperation.overwriteQuestion", new Object[] { pathString }); //$NON-NLS-1$
				final String[] options =
					{
						IDialogConstants.YES_LABEL,
						IDialogConstants.YES_TO_ALL_LABEL,
						IDialogConstants.NO_LABEL,
						IDialogConstants.CANCEL_LABEL };
				parentShell.getDisplay().syncExec(new Runnable() {
					public void run() {
						MessageDialog dialog = new MessageDialog(parentShell, IDEWorkbenchMessages.getString("CopyFilesAndFoldersOperation.question"), null, msg, MessageDialog.QUESTION, options, 0); //$NON-NLS-1$
						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(),
				null,
				FileSystemStructureProvider.INSTANCE,
				query,
				Arrays.asList(files));
		op.setContext(parentShell);
		op.setCreateContainerStructure(false);
		try {
			op.run(monitor);
		} catch (InterruptedException e) {
			return;
		} catch (InvocationTargetException e) {
			if (e.getTargetException() instanceof CoreException) {
				final IStatus status = ((CoreException) e.getTargetException()).getStatus();
				parentShell.getDisplay().syncExec(new Runnable() {
					public void run() {
						ErrorDialog.openError(parentShell, IDEWorkbenchMessages.getString("CopyFilesAndFoldersOperation.importErrorDialogTitle"), //$NON-NLS-1$
						null, // no special message
						status);
					}
				});
			} else {
				// CoreExceptions are handled above, but unexpected runtime exceptions and errors may still occur.
				Platform.getPlugin(PlatformUI.PLUGIN_ID).getLog().log(StatusUtil.newStatus(IStatus.ERROR, MessageFormat.format("Exception in {0}.performFileImport(): {1}", //$NON-NLS-1$
				new Object[] { getClass().getName(), e.getTargetException()}), null));
				displayError(IDEWorkbenchMessages.format("CopyFilesAndFoldersOperation.internalError", //$NON-NLS-1$
				new Object[] { e.getTargetException().getMessage()}));
			}
			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); //$NON-NLS-1$
			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); //$NON-NLS-1$

		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.getString("CopyFilesAndFoldersOperation.destinationAccessError"); //$NON-NLS-1$
		}
		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.getString("CopyFilesAndFoldersOperation.parentNotEqual");	//$NON-NLS-1$					
			}
			
			IPath sourceLocation = sourceResource.getLocation();
			if (sourceLocation == null) {
				if (sourceResource.isLinked()) {
					// Don't allow copying linked resources with undefined path 
					// variables. See bug 28754.
					return IDEWorkbenchMessages.format(
						"CopyFilesAndFoldersOperation.missingPathVariable",		//$NON-NLS-1$
						new Object[] {sourceResource.getName()});				
				} else {
					return IDEWorkbenchMessages.format(
						"CopyFilesAndFoldersOperation.resourceDeleted",		//$NON-NLS-1$
						new Object[] {sourceResource.getName()});				
				}
			} else {
				if (sourceLocation.equals(destinationLocation)) {
					return IDEWorkbenchMessages.format(
						"CopyFilesAndFoldersOperation.sameSourceAndDest", 	//$NON-NLS-1$
						new Object[] {sourceResource.getName()});
				}
				// is the source a parent of the destination?
				if (sourceLocation.isPrefixOf(destinationLocation)) {
					return IDEWorkbenchMessages.getString("CopyFilesAndFoldersOperation.destinationDescendentError"); //$NON-NLS-1$
				}
			}
			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 IDEWorkbenchMessages.format(
					"CopyFilesAndFoldersOperation.missingPathVariable",		//$NON-NLS-1$
					new Object[] {destination.getName()});				
			}
			else {
				return IDEWorkbenchMessages.format(
					"CopyFilesAndFoldersOperation.resourceDeleted",			//$NON-NLS-1$
					new Object[] {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, parentShell);
			
			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) {
		if (!isAccessible(destination)) {
			return IDEWorkbenchMessages.getString("CopyFilesAndFoldersOperation.destinationAccessError"); //$NON-NLS-1$
		}
		String destinationMessage = validateDestinationLocation(destination);
		if (destinationMessage != null) {
			return destinationMessage;
		}
		// work around bug 16202. revert when fixed.
		IPath destinationPath = destination.getLocation();
		File destinationFile = destinationPath.toFile();		
		for (int i = 0; i < sourceNames.length; i++) {
			IPath sourcePath = new Path(sourceNames[i]);
			File sourceFile = sourcePath.toFile();
			File sourceParentFile = sourcePath.removeLastSegments(1).toFile();			
			if (sourceFile != null) {
				if (destinationFile.compareTo(sourceFile) == 0 || 
					(sourceParentFile != null && destinationFile.compareTo(sourceParentFile) == 0)) {
					return IDEWorkbenchMessages.format("CopyFilesAndFoldersOperation.importSameSourceAndDest", //$NON-NLS-1$
					new Object[] {sourceFile.getName()});
				}
				// work around bug 16202. replacement for sourcePath.isPrefixOf(destinationPath)
				IPath destinationParent = destinationPath.removeLastSegments(1);
				while (destinationParent.isEmpty() == false && destinationParent.isRoot() == false) {
					destinationFile = destinationParent.toFile();
					if (sourceFile.compareTo(destinationFile) == 0) {
						return IDEWorkbenchMessages.getString("CopyFilesAndFoldersOperation.destinationDescendentError"); //$NON-NLS-1$
					}
					destinationParent = destinationParent.removeLastSegments(1);
				}
			}
		}
		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 IDEWorkbenchMessages.format(
							"CopyFilesAndFoldersOperation.sameSourceAndDest", //$NON-NLS-1$
							new Object[] {source.getName()});
					}
				}
			}
			catch (CoreException exception) {
				displayError(IDEWorkbenchMessages.format(
					"CopyFilesAndFoldersOperation.internalError", 				//$NON-NLS-1$
					new Object[] {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 
	 * @param monitor a progress monitor for showing progress and for 
	 * 	cancelation
	 * @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,
		IProgressMonitor monitor) {
		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)) {
				//Run it inside of a runnable to make sure we get to parent off of the shell as we are not
				//in the UI thread.
				Runnable notice = new Runnable() {
					public void run() {
						MessageDialog.openError(
							parentShell, 
							IDEWorkbenchMessages.getString("CopyFilesAndFoldersOperation.overwriteProblemTitle"), //$NON-NLS-1$
							IDEWorkbenchMessages.format(
								"CopyFilesAndFoldersOperation.overwriteProblem", //$NON-NLS-1$
								new Object[] {destinationPath, sourcePath}
							)
						);
					}
				};
				parentShell.getDisplay().syncExec(notice);
				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(parentShell, 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()]);
	}
}
