/*******************************************************************************
 * Copyright (c) 2000, 2020 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.ui.refactoring.reorg;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.FileTransfer;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.dnd.TransferData;
import org.eclipse.swt.widgets.Shell;

import org.eclipse.core.runtime.Assert;
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.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IEncodedStorage;
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.IStorage;

import org.eclipse.core.filebuffers.ITextFileBuffer;

import org.eclipse.text.edits.MalformedTreeException;
import org.eclipse.text.edits.TextEdit;

import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableContext;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.viewers.IStructuredSelection;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.DocumentRewriteSession;
import org.eclipse.jface.text.DocumentRewriteSessionType;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentExtension4;

import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IWorkbenchSite;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.CopyFilesAndFoldersOperation;
import org.eclipse.ui.actions.CopyProjectOperation;
import org.eclipse.ui.part.ResourceTransfer;

import org.eclipse.compare.CompareConfiguration;
import org.eclipse.compare.patch.ApplyPatchOperation;

import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.Refactoring;
import org.eclipse.ltk.core.refactoring.RefactoringCore;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.TextFileChange;

import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IPackageDeclaration;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.ToolFactory;
import org.eclipse.jdt.core.compiler.IScanner;
import org.eclipse.jdt.core.compiler.ITerminalSymbols;
import org.eclipse.jdt.core.compiler.InvalidInputException;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
import org.eclipse.jdt.core.dom.Block;
import org.eclipse.jdt.core.dom.BodyDeclaration;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.Javadoc;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.jdt.core.dom.Modifier.ModifierKeyword;
import org.eclipse.jdt.core.dom.PackageDeclaration;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.Statement;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
import org.eclipse.jdt.core.dom.rewrite.ITrackedNodePosition;
import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
import org.eclipse.jdt.core.manipulation.CodeGeneration;
import org.eclipse.jdt.core.refactoring.CompilationUnitChange;

import org.eclipse.jdt.internal.core.manipulation.StubUtility;
import org.eclipse.jdt.internal.core.manipulation.util.BasicElementLabels;
import org.eclipse.jdt.internal.core.manipulation.util.Strings;
import org.eclipse.jdt.internal.corext.dom.BodyDeclarationRewrite;
import org.eclipse.jdt.internal.corext.dom.IASTSharedValues;
import org.eclipse.jdt.internal.corext.refactoring.Checks;
import org.eclipse.jdt.internal.corext.refactoring.TypedSource;
import org.eclipse.jdt.internal.corext.refactoring.changes.TextChangeCompatibility;
import org.eclipse.jdt.internal.corext.refactoring.reorg.IConfirmQuery;
import org.eclipse.jdt.internal.corext.refactoring.reorg.IReorgQueries;
import org.eclipse.jdt.internal.corext.refactoring.reorg.JavaElementTransfer;
import org.eclipse.jdt.internal.corext.refactoring.reorg.ParentChecker;
import org.eclipse.jdt.internal.corext.refactoring.reorg.ReorgDestinationFactory;
import org.eclipse.jdt.internal.corext.refactoring.reorg.ReorgUtils;
import org.eclipse.jdt.internal.corext.refactoring.structure.ASTNodeSearchUtil;
import org.eclipse.jdt.internal.corext.refactoring.util.RefactoringFileBuffers;
import org.eclipse.jdt.internal.corext.refactoring.util.ResourceUtil;
import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
import org.eclipse.jdt.internal.corext.util.JdtFlags;
import org.eclipse.jdt.internal.corext.util.Messages;

import org.eclipse.jdt.launching.IVMInstall;
import org.eclipse.jdt.launching.IVMInstall2;
import org.eclipse.jdt.launching.IVMInstallType;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jdt.launching.environments.IExecutionEnvironment;
import org.eclipse.jdt.launching.environments.IExecutionEnvironmentsManager;

import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jdt.ui.PreferenceConstants;
import org.eclipse.jdt.ui.actions.SelectionDispatchAction;
import org.eclipse.jdt.ui.refactoring.RefactoringSaveHelper;

import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
import org.eclipse.jdt.internal.ui.IJavaStatusConstants;
import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.JavaUIMessages;
import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility;
import org.eclipse.jdt.internal.ui.refactoring.RefactoringExecutionHelper;
import org.eclipse.jdt.internal.ui.refactoring.RefactoringMessages;
import org.eclipse.jdt.internal.ui.util.BusyIndicatorRunnableContext;
import org.eclipse.jdt.internal.ui.util.ExceptionHandler;
import org.eclipse.jdt.internal.ui.util.SelectionUtil;
import org.eclipse.jdt.internal.ui.wizards.buildpaths.BuildPathsBlock;
import org.eclipse.jdt.internal.ui.workingsets.IWorkingSetIDs;


public class PasteAction extends SelectionDispatchAction{

	public static final String ID= "org.eclipse.jdt.internal.ui.refactoring.reorg.PasteAction.id"; //$NON-NLS-1$

	private final Clipboard fClipboard;

	public PasteAction(IWorkbenchSite site) {
		this(site, null);
	}

	public PasteAction(IWorkbenchSite site, Clipboard clipboard) {
		super(site);
		fClipboard= clipboard;

		setId(ID);
		setText(ReorgMessages.PasteAction_4);
		setDescription(ReorgMessages.PasteAction_5);

		ISharedImages workbenchImages= PlatformUI.getWorkbench().getSharedImages();
		setDisabledImageDescriptor(workbenchImages.getImageDescriptor(ISharedImages.IMG_TOOL_PASTE_DISABLED));
		setImageDescriptor(workbenchImages.getImageDescriptor(ISharedImages.IMG_TOOL_PASTE));
		setHoverImageDescriptor(workbenchImages.getImageDescriptor(ISharedImages.IMG_TOOL_PASTE));

		PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IJavaHelpContextIds.PASTE_ACTION);
	}

	@Override
	public void selectionChanged(IStructuredSelection selection) {
		// Moved condition checking to run (see http://bugs.eclipse.org/bugs/show_bug.cgi?id=78450)
	}

	private Paster[] createEnabledPasters(TransferData[] availableDataTypes, Clipboard clipboard) {
		Paster paster;
		Shell shell = getShell();
		List<Paster> result= new ArrayList<>(2);
		paster= new ProjectPaster(shell, clipboard);
		if (paster.canEnable(availableDataTypes))
			result.add(paster);

		paster= new JavaElementAndResourcePaster(shell, clipboard);
		if (paster.canEnable(availableDataTypes))
			result.add(paster);

		paster= new TypedSourcePaster(shell, clipboard);
		if (paster.canEnable(availableDataTypes))
			result.add(paster);

		paster= new FilePaster(shell, clipboard);
		if (paster.canEnable(availableDataTypes))
			result.add(paster);

		paster= new WorkingSetPaster(shell, clipboard);
		if (paster.canEnable(availableDataTypes))
			result.add(paster);

		paster= new TextPaster(shell, clipboard);
		if (paster.canEnable(availableDataTypes))
			result.add(paster);
		return result.toArray(new Paster[result.size()]);
	}

	private static Object getContents(final Clipboard clipboard, final Transfer transfer, Shell shell) {
		//see bug 33028 for explanation why we need this
		final Object[] result= new Object[1];
		shell.getDisplay().syncExec(() -> result[0]= clipboard.getContents(transfer));
		return result[0];
	}

	private static boolean isAvailable(Transfer transfer, TransferData[] availableDataTypes) {
		for (TransferData availableDataType : availableDataTypes) {
			if (transfer.isSupportedType(availableDataType)) {
				return true;
			}
		}
		return false;
	}

	@Override
	public void run(IStructuredSelection selection) {
		Clipboard clipboard;
		if (fClipboard != null)
			clipboard= fClipboard;
		else
			clipboard= new Clipboard(getShell().getDisplay());
		try {
			TransferData[] availableTypes= clipboard.getAvailableTypes();
			List<?> elements= selection.toList();
			IResource[] resources= ReorgUtils.getResources(elements);
			IJavaElement[] javaElements= ReorgUtils.getJavaElements(elements);
			IWorkingSet[] workingSets= ReorgUtils.getWorkingSets(elements);
			for (Paster paster : createEnabledPasters(availableTypes, clipboard)) {
				try {
					if (paster.canPasteOn(javaElements, resources, workingSets, elements)) {
						paster.paste(javaElements, resources, workingSets, availableTypes);
						return;// one is enough
					}
				} catch (JavaModelException e) {
					ExceptionHandler.handle(e, RefactoringMessages.OpenRefactoringWizardAction_refactoring, RefactoringMessages.OpenRefactoringWizardAction_exception);
				} catch (InvocationTargetException e) {
					ExceptionHandler.handle(e, RefactoringMessages.OpenRefactoringWizardAction_refactoring, RefactoringMessages.OpenRefactoringWizardAction_exception);
				} catch (InterruptedException e) {
					// user canceled the paste operation
					return;
				}
			}
			String msg= resources.length + javaElements.length + workingSets.length == 0
			? ReorgMessages.PasteAction_cannot_no_selection
					: ReorgMessages.PasteAction_cannot_selection;
			MessageDialog.openError(JavaPlugin.getActiveWorkbenchShell(), ReorgMessages.PasteAction_name, msg);
		} finally {
			if (fClipboard == null)
				clipboard.dispose();
		}
	}

	private abstract static class Paster{
		private final Shell fShell;
		private final Clipboard fClipboard2;
		protected Paster(Shell shell, Clipboard clipboard){
			fShell= shell;
			fClipboard2= clipboard;
		}
		protected final Shell getShell() {
			return fShell;
		}
		protected final Clipboard getClipboard() {
			return fClipboard2;
		}

		protected final IResource[] getClipboardResources(TransferData[] availableDataTypes) {
			Transfer transfer= ResourceTransfer.getInstance();
			if (isAvailable(transfer, availableDataTypes)) {
				return (IResource[])getContents(fClipboard2, transfer, getShell());
			}
			return null;
		}

		protected final IJavaElement[] getClipboardJavaElements(TransferData[] availableDataTypes) {
			Transfer transfer= JavaElementTransfer.getInstance();
			if (isAvailable(transfer, availableDataTypes)) {
				return (IJavaElement[])getContents(fClipboard2, transfer, getShell());
			}
			return null;
		}

		protected final TypedSource[] getClipboardTypedSources(TransferData[] availableDataTypes) {
			Transfer transfer= TypedSourceTransfer.getInstance();
			if (isAvailable(transfer, availableDataTypes)) {
				return (TypedSource[])getContents(fClipboard2, transfer, getShell());
			}
			return null;
		}

		protected final String getClipboardText(TransferData[] availableDataTypes) {
			Transfer transfer= TextTransfer.getInstance();
			if (isAvailable(transfer, availableDataTypes)) {
				return (String) getContents(fClipboard2, transfer, getShell());
			}
			return null;
		}

		/**
		 * Used to be called on selection change, but is only called on execution now (before
		 * {@link #canPasteOn(IJavaElement[], IResource[], IWorkingSet[], List)}).
		 *
		 * @param availableTypes transfer types
		 * @return whether the paste action can be enabled
		 */
		public abstract boolean canEnable(TransferData[] availableTypes);

		/*
		 * Only called if {@link #canEnable(TransferData[])} returns <code>true</code>.
		 */
		public abstract boolean canPasteOn(IJavaElement[] selectedJavaElements, IResource[] selectedResources, IWorkingSet[] selectedWorkingSets, List<?> selectedElements)  throws JavaModelException;

		/*
		 * only called if {@link #canPasteOn(IJavaElement[], IResource[], IWorkingSet[])} returns <code>true</code>
		 */
		public abstract void paste(IJavaElement[] selectedJavaElements, IResource[] selectedResources, IWorkingSet[] selectedWorkingSets, TransferData[] availableTypes) throws JavaModelException, InterruptedException, InvocationTargetException;
	}

	private static class TextPaster extends Paster {

		private static class ParsedCu {
			private final String fText;
			private final int fKind;
			private final String fTypeName;
			private final String fPackageName;
			private final boolean fIsModuleInfo;

			public static List<ParsedCu> parseCus(IJavaProject javaProject, String compilerCompliance, String text) {
				ASTParser parser= ASTParser.newParser(IASTSharedValues.SHARED_AST_LEVEL);
				if (javaProject != null) {
					parser.setProject(javaProject);
				} else if (compilerCompliance != null) {
					Map<String, String> options= JavaCore.getOptions();
					JavaModelUtil.setComplianceOptions(options, compilerCompliance);
					parser.setCompilerOptions(options);
				}
				parser.setSource(text.toCharArray());
				parser.setStatementsRecovery(true);
				CompilationUnit unit= (CompilationUnit) parser.createAST(null);

				if (unit.types().size() > 0)
					return parseAsTypes(text, unit);

				if (javaProject != null) {
					parser.setProject(javaProject);
				} else if (compilerCompliance != null) {
					Map<String, String> options= JavaCore.getOptions();
					JavaModelUtil.setComplianceOptions(options, compilerCompliance);
					parser.setCompilerOptions(options);
				}
				parser.setSource(text.toCharArray());
				parser.setStatementsRecovery(true);
				parser.setUnitName(JavaModelUtil.MODULE_INFO_JAVA);
				unit= (CompilationUnit) parser.createAST(null);
				if (unit.getModule() != null) {
					return Collections.singletonList(new ParsedCu(text, ASTParser.K_COMPILATION_UNIT, null, null, true));
				}

				parser.setProject(javaProject);
				parser.setSource(text.toCharArray());
				parser.setStatementsRecovery(true);
				parser.setKind(ASTParser.K_CLASS_BODY_DECLARATIONS);
				ASTNode root= parser.createAST(null);
				if (root instanceof TypeDeclaration) {
					List<BodyDeclaration> bodyDeclarations= ((TypeDeclaration) root).bodyDeclarations();
					if (bodyDeclarations.size() > 0)
						return Collections.singletonList(new ParsedCu(text, ASTParser.K_CLASS_BODY_DECLARATIONS, null, null));
				}

				parser.setProject(javaProject);
				parser.setSource(text.toCharArray());
				parser.setStatementsRecovery(true);
				parser.setKind(ASTParser.K_STATEMENTS);
				root= parser.createAST(null);
				if (root instanceof Block) {
					List<Statement> statements= ((Block) root).statements();
					if (statements.size() > 0)
						return Collections.singletonList(new ParsedCu(text, ASTParser.K_STATEMENTS, null, null));
				}

				return Collections.emptyList();
			}

			private static List<ParsedCu> parseAsTypes(String text, CompilationUnit unit) {
				String packageName= IPackageFragment.DEFAULT_PACKAGE_NAME;
				PackageDeclaration pack= unit.getPackage();
				if (pack != null) {
					packageName= pack.getName().getFullyQualifiedName();
				}

				ArrayList<ParsedCu> cus= new ArrayList<>();
				List<AbstractTypeDeclaration> types= unit.types();

				int startOffset= 0;
				String typeName= null;
				int maxVisibility= JdtFlags.VISIBILITY_CODE_INVALID;

				// Public types must be in separate CUs:
				for (AbstractTypeDeclaration type : types) {
					if (typeName == null) {
						// first in group:
						maxVisibility= JdtFlags.getVisibilityCode(type);
						typeName= type.getName().getIdentifier();
					} else {
						int visibility= JdtFlags.getVisibilityCode(type);
						if (visibility == Modifier.PUBLIC && maxVisibility == Modifier.PUBLIC) {
							// public and there was a public type before => create CU for previous:
							int prevEnd= type.getStartPosition();
							String source= text.substring(startOffset, prevEnd);
							cus.add(new ParsedCu(source, ASTParser.K_COMPILATION_UNIT, typeName, packageName));
							// ... and restart:
							startOffset= prevEnd;
							typeName= type.getName().getIdentifier();
							maxVisibility= visibility;
						} else {
							if (JdtFlags.isHigherVisibility(visibility, maxVisibility)) {
								maxVisibility= visibility;
								typeName= type.getName().getIdentifier();
							}
						}
					}
				}
				if (typeName != null) {
					// create CU for the rest:
					String source= text.substring(startOffset);
					cus.add(new ParsedCu(source, ASTParser.K_COMPILATION_UNIT, typeName, packageName));
				}
				return cus;
			}

			private ParsedCu(String text, int kind, String typeName, String packageName) {
				this(text, kind, typeName, packageName, false);
			}

			private ParsedCu(String text, int kind, String typeName, String packageName, boolean isModuleInfo) {
				fText= text;
				fTypeName= typeName;
				fPackageName= packageName;
				fKind= kind;
				fIsModuleInfo= isModuleInfo;
			}

			public String getTypeName() {
				return fTypeName;
			}

			public String getPackageName() {
				return fPackageName;
			}

			public String getText() {
				return fText;
			}

			public int getKind() {
				return fKind;
			}
		}

		private IStorage fPatchStorage;

		private IPackageFragmentRoot fDestination;
		/**
		 * destination pack iff pasted 1 CU to package fragment or compilation unit, <code>null</code> otherwise
		 */
		private IPackageFragment fDestinationPack;
		private IType fDestinationType;
		private IMethod fDestinationMethod;
		private int fPackageDeclCount;
		private ParsedCu[] fParsedCus;
		private TransferData[] fAvailableTypes;
		private IPath fVMPath;
		private String fCompilerCompliance;

		protected TextPaster(Shell shell, Clipboard clipboard) {
			super(shell, clipboard);
		}

		@Override
		public boolean canEnable(TransferData[] availableTypes) {
			fAvailableTypes= availableTypes;
			return PasteAction.isAvailable(TextTransfer.getInstance(), availableTypes) && ! PasteAction.isAvailable(FileTransfer.getInstance(), availableTypes);
		}

		@Override
		public boolean canPasteOn(IJavaElement[] javaElements, IResource[] resources, IWorkingSet[] selectedWorkingSets, List<?> selectedElements) throws JavaModelException {
			final String text= getClipboardText(fAvailableTypes);

			IStorage storage= new IEncodedStorage() {
				@Override
				public <T> T getAdapter(Class<T> adapter) {
					return null;
				}
				@Override
				public boolean isReadOnly() {
					return false;
				}
				@Override
				public String getName() {
					return null;
				}
				@Override
				public IPath getFullPath() {
					return null;
				}
				@Override
				public InputStream getContents() throws CoreException {
					try {
						return new ByteArrayInputStream(text.getBytes(getCharset()));
					} catch (UnsupportedEncodingException e) {
						throw new CoreException(new Status(IStatus.ERROR, JavaPlugin.getPluginId(),
								IJavaStatusConstants.INTERNAL_ERROR, JavaUIMessages.JavaPlugin_internal_error, e));
					}
				}
				@Override
				public String getCharset() throws CoreException {
					return "UTF-8"; //$NON-NLS-1$
				}
			};
			try {
				if (ApplyPatchOperation.isPatch(storage)) {
					fPatchStorage= storage;
					return true;
				}
			} catch (CoreException e) {
				// continue
			}


			if (selectedWorkingSets.length > 1)
				return false;
			if (resources.length != 0)
				return false; //alternative: create text file?
			if (javaElements.length > 1)
				return false;

			IJavaProject javaProject= null;
			IJavaElement destination= null;
			if (javaElements.length == 1) {
				destination= javaElements[0];
				javaProject= destination.getJavaProject();
			} else if (selectedWorkingSets.length == 1) {
				// OK
			} else if (!selectedElements.isEmpty()) {
				return false; // e.g. ClassPathContainer
			}

			computeLatestVM();
			parseCUs(javaProject, text);

			if (fParsedCus.length == 0)
				return false;

			if (destination == null)
				return true;

			/*
			 * 0 to 1 package declarations in source: paste into package, adapt package declarations
			 * 2+ package declarations: always paste into source folder
			 */

			IPackageFragmentRoot packageFragmentRoot;
			IPackageFragment destinationPack;
			IJavaElement cu;
			switch (destination.getElementType()) {
				case IJavaElement.JAVA_PROJECT :
					for (IPackageFragmentRoot fragmentroot : ((IJavaProject) destination).getPackageFragmentRoots()) {
						packageFragmentRoot= fragmentroot;
						if (isWritable(packageFragmentRoot)) {
							fDestination= packageFragmentRoot;
							return true;
						}
					}
					return false;

				case IJavaElement.PACKAGE_FRAGMENT_ROOT :
					packageFragmentRoot= (IPackageFragmentRoot) destination;
					if (isWritable(packageFragmentRoot)) {
						fDestination= packageFragmentRoot;
						return true;
					}
					return false;

				case IJavaElement.PACKAGE_FRAGMENT :
					destinationPack= (IPackageFragment) destination;
					packageFragmentRoot= (IPackageFragmentRoot) destinationPack.getParent();
					if (isWritable(packageFragmentRoot)) {
						fDestination= packageFragmentRoot;
						if (fPackageDeclCount <= 1) {
							fDestinationPack= destinationPack;
						}
						return true;
					}
					return false;

				case IJavaElement.COMPILATION_UNIT :
					destinationPack= (IPackageFragment) destination.getParent();
					packageFragmentRoot= (IPackageFragmentRoot) destinationPack.getParent();
					if (isWritable(packageFragmentRoot)) {
						fDestination= packageFragmentRoot;
						if (fPackageDeclCount <= 1) {
							fDestinationPack= destinationPack;
							fDestinationType= ((ICompilationUnit) destination).findPrimaryType();
						}
						return true;
					}
					return false;

				case IJavaElement.TYPE:
					cu= ((IType) destination).getCompilationUnit();
					if (cu != null) {
						fDestinationType= (IType) destination;
						fDestinationPack= (IPackageFragment) cu.getParent();
						fDestination= (IPackageFragmentRoot) fDestinationPack.getParent();
						return true;
					}
					return false;

				case IJavaElement.METHOD:
					cu= ((IMethod) destination).getCompilationUnit();
					if (cu != null) {
						fDestinationMethod= (IMethod) destination;
						fDestinationType= (IType) destination.getParent();
						fDestinationPack= (IPackageFragment) cu.getParent();
						fDestination= (IPackageFragmentRoot) fDestinationPack.getParent();
						return true;
					}
					return false;

				default:
					return false;
			}
		}

		private boolean isWritable(IPackageFragmentRoot packageFragmentRoot) {
			try {
				return packageFragmentRoot.exists() && ! packageFragmentRoot.isArchive() && ! packageFragmentRoot.isReadOnly()
						&& packageFragmentRoot.getKind() == IPackageFragmentRoot.K_SOURCE;
			} catch (JavaModelException e) {
				return false;
			}
		}

		@Override
		public void paste(IJavaElement[] javaElements, IResource[] resources, final IWorkingSet[] selectedWorkingSets, TransferData[] availableTypes) throws JavaModelException, InterruptedException, InvocationTargetException{
			if (fPatchStorage != null) {
				IResource resource= null;
				if (resources.length > 0) {
					resource= resources[0];
				} else if (javaElements.length > 0) {
					resource= javaElements[0].getResource();
				}
				// XXX: This will be fixed in 3.7, see https://bugs.eclipse.org/309803
				new org.eclipse.team.internal.ui.synchronize.patch.ApplyPatchOperation(null, fPatchStorage, resource, new CompareConfiguration()).openWizard();
				return;
			}

			final IEditorPart[] editorPart= new IEditorPart[1];

			IRunnableWithProgress op= new IRunnableWithProgress() {
				@Override
				public void run(IProgressMonitor monitor) throws InvocationTargetException {

					final ArrayList<ICompilationUnit> cus= new ArrayList<>();
					try {
						JavaCore.run(pm -> {
							pm.beginTask("", 1 + fParsedCus.length); //$NON-NLS-1$

							if (fDestination == null) {
								fDestination= createNewProject(new SubProgressMonitor(pm, 1));
							} else {
								pm.worked(1);
							}
							IConfirmQuery confirmQuery= new ReorgQueries(getShell()).createYesYesToAllNoNoToAllQuery(ReorgMessages.PasteAction_TextPaster_confirmOverwriting, true, IReorgQueries.CONFIRM_OVERWRITING);
							for (ParsedCu parsedCu : fParsedCus) {
								if (pm.isCanceled())
									break;
								ICompilationUnit cu= pasteCU(parsedCu, new SubProgressMonitor(pm, 1), confirmQuery);
								if (cu != null)
									cus.add(cu);
							}

							if (selectedWorkingSets.length == 1) {
								IWorkingSet ws= selectedWorkingSets[0];
								if (!IWorkingSetIDs.OTHERS.equals(ws.getId())) {
									ArrayList<IAdaptable> newElements= new ArrayList<>();
									newElements.addAll(Arrays.asList(ws.getElements()));
									newElements.addAll(Arrays.asList(ws.adaptElements(new IAdaptable[] { fDestination.getJavaProject() })));
									ws.setElements(newElements.toArray(new IAdaptable[newElements.size()]));
								}
							}
						}, monitor);
					} catch (OperationCanceledException e) {
						// cancelling is fine
					} catch (CoreException e) {
						throw new InvocationTargetException(e);
					} finally {
						monitor.done();
					}
					IResource[] cuResources= ResourceUtil.getFiles(cus.toArray(new ICompilationUnit[cus.size()]));
					SelectionUtil.selectAndReveal(cuResources, PlatformUI.getWorkbench().getActiveWorkbenchWindow());
				}

				private ICompilationUnit pasteCU(ParsedCu parsedCu, IProgressMonitor pm, IConfirmQuery confirmQuery) throws CoreException, OperationCanceledException {
					pm.beginTask("", 4); //$NON-NLS-1$
					try {
						IPackageFragment destinationPack;
						if (parsedCu.fIsModuleInfo) {
							destinationPack= fDestination.getPackageFragment(""); //$NON-NLS-1$ // the default package
							pm.worked(1);
						} else {
							if (fDestinationPack != null) {
								destinationPack= fDestinationPack;
								pm.worked(1);
							} else {
								String packageName= parsedCu.getPackageName();
								if (packageName == null)
									packageName= ReorgMessages.PasteAction_snippet_default_package_name;
								destinationPack= fDestination.getPackageFragment(packageName);
								if (!destinationPack.exists()) {
									JavaModelUtil.getPackageFragmentRoot(destinationPack).createPackageFragment(packageName, true, new SubProgressMonitor(pm, 1));
								} else {
									pm.worked(1);
								}
							}
						}

						String parsedText= Strings.trimIndentation(parsedCu.getText(), destinationPack.getJavaProject(), true);
						int kind= parsedCu.getKind();
						if (kind == ASTParser.K_COMPILATION_UNIT) {
							final String cuName;
							if (parsedCu.fIsModuleInfo) {
								cuName= JavaModelUtil.MODULE_INFO_JAVA;
							} else {
								cuName= parsedCu.getTypeName() + JavaModelUtil.DEFAULT_CU_SUFFIX;
							}
							ICompilationUnit cu= destinationPack.getCompilationUnit(cuName);
							boolean alreadyExists= cu.exists();
							if (alreadyExists) {
								String msg= Messages.format(ReorgMessages.PasteAction_TextPaster_exists, new Object[] { BasicElementLabels.getResourceName(cuName)});
								boolean overwrite= confirmQuery.confirm(msg);
								if (! overwrite)
									return null;

								editorPart[0]= openCu(cu); //Open editor before overwriting to allow undo to restore original package declaration
							}

							parsedText= parsedText.replaceAll("\r\n?|\n", StubUtility.getLineDelimiterUsed(cu)); //$NON-NLS-1$
							destinationPack.createCompilationUnit(cuName, parsedText, true, new SubProgressMonitor(pm, 1));

							if (! alreadyExists) {
								editorPart[0]= openCu(cu);
							}
							if (fDestinationPack != null) {
								if (fDestinationPack.getElementName().length() == 0) {
									removePackageDeclaration(cu);
								} else {
									cu.createPackageDeclaration(fDestinationPack.getElementName(), new SubProgressMonitor(pm, 1));
								}
							} else {
								String packageName= destinationPack.getElementName();
								if (packageName.length() > 0) {
									cu.createPackageDeclaration(packageName, new SubProgressMonitor(pm, 1));
								}
							}
							if (! alreadyExists && editorPart[0] != null)
								editorPart[0].doSave(new SubProgressMonitor(pm, 1)); //avoid showing error marker due to missing/wrong package declaration
							return cu;

						} else if (kind == ASTParser.K_CLASS_BODY_DECLARATIONS || kind == ASTParser.K_STATEMENTS) {
							return pasteBodyDeclsOrStatements(destinationPack, parsedText, kind, new SubProgressMonitor(pm, 2));
						} else {
							throw new IllegalStateException("Unexpected kind: " + kind); //$NON-NLS-1$
						}
					} finally {
						pm.done();
					}
				}

				private ICompilationUnit pasteBodyDeclsOrStatements(IPackageFragment destinationPack, String parsedText, int kind, IProgressMonitor pm) throws CoreException, JavaModelException {
					ICompilationUnit cu;
					IType type;
					String typeName;
					if (fDestinationType != null) {
						cu= fDestinationType.getCompilationUnit();
						type= fDestinationType;
						typeName= fDestinationType.getElementName();
					} else {
						typeName= ReorgMessages.PasteAction_snippet_default_type_name;
						cu= destinationPack.getCompilationUnit(typeName + JavaModelUtil.DEFAULT_CU_SUFFIX);
						type= cu.getType(typeName);
					}
					if (cu.exists()) {
						editorPart[0]= openCu(cu); //Open editor before pasting to allow undo to restore original contents
						ITextFileBuffer fileBuffer= RefactoringFileBuffers.acquire(cu);
						try {
							IDocument document= fileBuffer.getDocument();

							ASTParser parser= ASTParser.newParser(IASTSharedValues.SHARED_AST_LEVEL);
							parser.setProject(cu.getJavaProject());
							parser.setSource(document.get().toCharArray());
							parser.setStatementsRecovery(true);
							CompilationUnit cuNode= (CompilationUnit) parser.createAST(pm);

							AbstractTypeDeclaration typeDecl= type.exists() ? ASTNodeSearchUtil.getAbstractTypeDeclarationNode(type, cuNode) : null;
							MethodDeclaration methodDecl= fDestinationMethod != null ? ASTNodeSearchUtil.getMethodDeclarationNode(fDestinationMethod, cuNode) : null;

							ITrackedNodePosition textPosition= createOrFillTypeDeclaration(cuNode, document, cu, typeDecl, typeName, methodDecl, kind, parsedText);
							EditorUtility.revealInEditor(editorPart[0], textPosition.getStartPosition() + textPosition.getLength(), 0);
							// leave unsaved
						} finally {
							RefactoringFileBuffers.release(cu);
						}

					} else {
						String delim= StubUtility.getLineDelimiterUsed(cu);
						String fileComment= null;
						if (StubUtility.doAddComments(cu.getJavaProject())) {
							fileComment= CodeGeneration.getFileComment(cu, delim);
						}
						String cuContent= CodeGeneration.getCompilationUnitContent(cu, fileComment, null, "", delim); //$NON-NLS-1$
						if (cuContent == null)
							cuContent= ""; //$NON-NLS-1$
						IDocument document= new Document(cuContent);

						ASTParser parser= ASTParser.newParser(IASTSharedValues.SHARED_AST_LEVEL);
						parser.setProject(cu.getJavaProject());
						parser.setSource(cuContent.toCharArray());
						parser.setStatementsRecovery(true);
						CompilationUnit cuNode= (CompilationUnit) parser.createAST(pm);

						ITrackedNodePosition textPosition= createOrFillTypeDeclaration(cuNode, document, cu, null, typeName, null, kind, parsedText);
						destinationPack.createCompilationUnit(cu.getElementName(), document.get(), false, null);
						editorPart[0]= openCu(cu);
						EditorUtility.revealInEditor(editorPart[0], textPosition.getStartPosition() + textPosition.getLength(), 0);
					}
					return cu;
				}

				private ITrackedNodePosition createOrFillTypeDeclaration(
						CompilationUnit cuNode,
						IDocument document,
						ICompilationUnit cu,
						AbstractTypeDeclaration typeDecl,
						String typeName,
						MethodDeclaration methodDecl,
						int kind,
						String parsedText) throws CoreException {

					AST ast= cuNode.getAST();
					ASTRewrite rewrite= ASTRewrite.create(ast);
					String delim= StubUtility.getLineDelimiterUsed(cu);

					if (typeDecl == null) {
						typeDecl= ast.newTypeDeclaration();
						typeDecl.getName().setIdentifier(typeName);
						if (StubUtility.doAddComments(cu.getJavaProject())) {
							String typeComment= CodeGeneration.getTypeComment(cu, typeName, delim);
							if (typeComment != null)
								typeDecl.setJavadoc((Javadoc) rewrite.createStringPlaceholder(typeComment, ASTNode.JAVADOC));
						}
						typeDecl.modifiers().add(ast.newModifier(ModifierKeyword.PUBLIC_KEYWORD));

						String typeBody= CodeGeneration.getTypeBody(CodeGeneration.CLASS_BODY_TEMPLATE_ID, cu, typeName, delim);
						if (typeBody != null) {
							BodyDeclaration typeBodyNode= (BodyDeclaration) rewrite.createStringPlaceholder(typeBody, ASTNode.METHOD_DECLARATION);
							ListRewrite bodyRewrite= rewrite.getListRewrite(typeDecl, typeDecl.getBodyDeclarationsProperty());
							bodyRewrite.insertFirst(typeBodyNode, null);
						}

						rewrite.getListRewrite(cuNode, CompilationUnit.TYPES_PROPERTY).insertLast(typeDecl, null);
					}

					ITrackedNodePosition textPosition;
					if (kind == ASTParser.K_CLASS_BODY_DECLARATIONS) {
						ListRewrite bodyRewrite= rewrite.getListRewrite(typeDecl, typeDecl.getBodyDeclarationsProperty());
						BodyDeclaration textNode= (BodyDeclaration) rewrite.createStringPlaceholder(parsedText, ASTNode.METHOD_DECLARATION);
						bodyRewrite.insertLast(textNode, null);
						textPosition= rewrite.track(textNode);

					} else { // kind == ASTParser.K_STATEMENTS
						if (methodDecl == null || methodDecl.getBody() == null) {
							methodDecl= ast.newMethodDeclaration();
							String qualifiedtypeName= fDestinationType != null ? fDestinationType.getFullyQualifiedName('.') : cu.getParent().getElementName() + '.' + typeName;
							if (StubUtility.doAddComments(cu.getJavaProject())) {
								String methodComment= CodeGeneration.getMethodComment(cu, qualifiedtypeName, methodDecl, null, delim);
								if (methodComment != null)
									methodDecl.setJavadoc((Javadoc) rewrite.createStringPlaceholder(methodComment, ASTNode.JAVADOC));
							}
							methodDecl.modifiers().addAll(ast.newModifiers(Modifier.PUBLIC | Modifier.STATIC));
							String methodName= "main"; //$NON-NLS-1$
							methodDecl.getName().setIdentifier(methodName);
							SingleVariableDeclaration param= ast.newSingleVariableDeclaration();
							param.setType(ast.newArrayType(ast.newSimpleType(ast.newSimpleName("String")))); //$NON-NLS-1$
							param.getName().setIdentifier("args"); //$NON-NLS-1$
							methodDecl.parameters().add(param);
							Block block= ast.newBlock();
							methodDecl.setBody(block);

							rewrite.getListRewrite(typeDecl, typeDecl.getBodyDeclarationsProperty()).insertLast(methodDecl, null);
						}
						Block body= methodDecl.getBody();
						ListRewrite statementsRewrite= rewrite.getListRewrite(body, Block.STATEMENTS_PROPERTY);
						Statement textNode= (Statement) rewrite.createStringPlaceholder(parsedText, ASTNode.EMPTY_STATEMENT);
						statementsRewrite.insertLast(textNode, null);
						textPosition= rewrite.track(textNode);
					}

					DocumentRewriteSession rewriteSession= null;
					if (document instanceof IDocumentExtension4)
						rewriteSession= ((IDocumentExtension4) document).startRewriteSession(DocumentRewriteSessionType.UNRESTRICTED_SMALL);
					TextEdit edit= rewrite.rewriteAST(document, cu.getJavaProject().getOptions(true));
					try {
						edit.apply(document, TextEdit.UPDATE_REGIONS);
						return textPosition;
					} catch (MalformedTreeException | BadLocationException e) {
						JavaPlugin.log(e);
					} finally {
						if (rewriteSession != null)
							((IDocumentExtension4) document).stopRewriteSession(rewriteSession);
					}
					return null;
				}

				private IPackageFragmentRoot createNewProject(SubProgressMonitor pm) throws CoreException {
					pm.beginTask("", 10); //$NON-NLS-1$
					IProject project;
					int i= 1;
					do {
						String name= Messages.format(ReorgMessages.PasteAction_projectName, i == 1 ? (Object) "" : Integer.valueOf(i)); //$NON-NLS-1$
						project= JavaPlugin.getWorkspace().getRoot().getProject(name);
						i++;
					} while (project.exists());

					BuildPathsBlock.createProject(project, null, new SubProgressMonitor(pm, 3));
					BuildPathsBlock.addJavaNature(project, new SubProgressMonitor(pm, 1));
					IJavaProject javaProject= JavaCore.create(project);

					IResource srcFolder;
					IPreferenceStore store= PreferenceConstants.getPreferenceStore();
					String sourceFolderName= store.getString(PreferenceConstants.SRCBIN_SRCNAME);
					if (store.getBoolean(PreferenceConstants.SRCBIN_FOLDERS_IN_NEWPROJ) && sourceFolderName.length() > 0) {
						IFolder folder= project.getFolder(sourceFolderName);
						if (! folder.exists()) {
							folder.create(false, true, new SubProgressMonitor(pm, 1));
						}
						srcFolder= folder;
					} else {
						srcFolder= project;
					}

					if (fCompilerCompliance != null) {
						Map<String, String> options= javaProject.getOptions(false);
						JavaModelUtil.setComplianceOptions(options, fCompilerCompliance);
						JavaModelUtil.setDefaultClassfileOptions(options, fCompilerCompliance);
						javaProject.setOptions(options);
					}
					IClasspathEntry srcEntry= JavaCore.newSourceEntry(srcFolder.getFullPath());
					IClasspathEntry jreEntry= JavaCore.newContainerEntry(fVMPath);
					IPath outputLocation= BuildPathsBlock.getDefaultOutputLocation(javaProject);
					IClasspathEntry[] cpes= new IClasspathEntry[] { srcEntry, jreEntry };
					javaProject.setRawClasspath(cpes, outputLocation, new SubProgressMonitor(pm, 1));
					return javaProject.getPackageFragmentRoot(srcFolder);
				}

				private void removePackageDeclaration(final ICompilationUnit cu) throws JavaModelException, CoreException {
					IPackageDeclaration[] packageDeclarations= cu.getPackageDeclarations();
					if (packageDeclarations.length != 0) {
						ITextFileBuffer buffer= null;
						try {
							buffer= RefactoringFileBuffers.acquire(cu);
							ISourceRange sourceRange= packageDeclarations[0].getSourceRange();
							buffer.getDocument().replace(sourceRange.getOffset(), sourceRange.getLength(), ""); //$NON-NLS-1$
						} catch (BadLocationException e) {
							JavaPlugin.log(e);
						} finally {
							if (buffer != null)
								RefactoringFileBuffers.release(cu);
						}
					}
				}
			};

			IRunnableContext context= JavaPlugin.getActiveWorkbenchWindow();
			if (context == null) {
				context= new BusyIndicatorRunnableContext();
			}
			//TODO: wrap op in workspace runnable and pass to JavaCore.run(..); take project creation out of UI thread.
			PlatformUI.getWorkbench().getProgressService().runInUI(context, op, JavaPlugin.getWorkspace().getRoot());

			if (editorPart[0] != null)
				editorPart[0].getEditorSite().getPage().activate(editorPart[0]); //activate editor again, since runInUI restores previous active part
		}

		private IEditorPart openCu(ICompilationUnit cu) {
			try {
				return JavaUI.openInEditor(cu, true, true);
			} catch (PartInitException | JavaModelException e) {
				JavaPlugin.log(e);
				return null;
			}
		}

		private void parseCUs(IJavaProject javaProject, String text) {
			IScanner scanner= ToolFactory.createScanner(false, false, false, false);
			scanner.setSource(text.toCharArray());

			ArrayList<ParsedCu> cus= new ArrayList<>();
			int start= 0;
			boolean tokensScanned= false;
			fPackageDeclCount= 0;
			int tok;
			while (true) {
				try {
					tok= scanner.getNextToken();
				} catch (InvalidInputException e) {
					// Handle gracefully to give the ASTParser a chance to recover,
					// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=168691
					tok= ITerminalSymbols.TokenNameEOF;
				}
				if (tok == ITerminalSymbols.TokenNamepackage) {
					fPackageDeclCount++;
					if (tokensScanned) {
						int packageStart= scanner.getCurrentTokenStartPosition();
						List<ParsedCu> parsed= ParsedCu.parseCus(javaProject, fCompilerCompliance, text.substring(start, packageStart));
						if (parsed.size() > 0) {
							cus.addAll(parsed);
							start= packageStart;
						}
					}
				} else if (tok == ITerminalSymbols.TokenNameEOF) {
					List<ParsedCu> parsed= ParsedCu.parseCus(javaProject, fCompilerCompliance, text.substring(start, text.length()));
					if (parsed.size() > 0) {
						cus.addAll(parsed);
					}
					break;
				}
				tokensScanned= true;
			}
			fParsedCus= cus.toArray(new ParsedCu[cus.size()]);
		}

		private void computeLatestVM() {
			IVMInstall bestVM= JavaRuntime.getDefaultVMInstall();
			String bestVersion= getVMVersion(bestVM);

			IExecutionEnvironmentsManager eeManager= JavaRuntime.getExecutionEnvironmentsManager();
			IExecutionEnvironment bestEE= null;

			outer: for (IExecutionEnvironment ee : eeManager.getExecutionEnvironments()) {
				IVMInstall vm= ee.getDefaultVM();
				String ver= getVMVersion(vm);
				if (ver != null) {
					if (bestVersion == null || JavaModelUtil.isVersionLessThan(bestVersion, ver) || bestVersion.equals(ver)) {
						bestVersion= ver;
						bestEE= ee;
					}
				} else {
					String eeVer= JavaModelUtil.getExecutionEnvironmentCompliance(ee);
					for (IVMInstall compatibleVM : ee.getCompatibleVMs()) {
						vm= compatibleVM;
						ver= getVMVersion(vm);
						if (!eeVer.equals(ver))
							continue; // don't want to set an EE where there's no strictly compatible VM
						if (bestVersion == null || JavaModelUtil.isVersionLessThan(bestVersion, ver) || bestVersion.equals(ver)) {
							bestVersion= ver;
							bestEE= ee;
							continue outer;
						}
					}
				}
			}

			for (IVMInstallType vmType : JavaRuntime.getVMInstallTypes()) {
				for (IVMInstall vm : vmType.getVMInstalls()) {
					String ver= getVMVersion(vm);
					if (ver != null && (bestVersion == null || JavaModelUtil.isVersionLessThan(bestVersion, ver))) {
						bestVersion= ver;
						bestVM= vm;
						bestEE= null;
					}
				}
			}

			if (bestEE != null) {
				fVMPath= JavaRuntime.newJREContainerPath(bestEE);
				fCompilerCompliance= bestVersion;
			} else if (bestVM != null) {
				fVMPath= JavaRuntime.newJREContainerPath(bestVM);
				fCompilerCompliance= bestVersion;
			} else {
				fVMPath= JavaRuntime.newDefaultJREContainerPath();
			}
		}

		private String getVMVersion(IVMInstall vm) {
			if (vm instanceof IVMInstall2) {
				IVMInstall2 vm2= (IVMInstall2) vm;
				return JavaModelUtil.getCompilerCompliance(vm2, null);
			} else {
				return null;
			}
		}
	}

	private static class WorkingSetPaster extends Paster {
		protected WorkingSetPaster(Shell shell, Clipboard clipboard) {
			super(shell, clipboard);
		}
		@Override
		public void paste(IJavaElement[] selectedJavaElements, IResource[] selectedResources, IWorkingSet[] selectedWorkingSets, TransferData[] availableTypes) throws JavaModelException, InterruptedException, InvocationTargetException {
			IWorkingSet workingSet= selectedWorkingSets[0];
			Set<IAdaptable> elements= new HashSet<>(Arrays.asList(workingSet.getElements()));
			IJavaElement[] javaElements= getClipboardJavaElements(availableTypes);
			if (javaElements != null) {
				for (IJavaElement javaElement : javaElements) {
					if (!ReorgUtils.containsElementOrParent(elements, javaElement)) {
						elements.add(javaElement);
					}
				}
			}
			IResource[] resources= getClipboardResources(availableTypes);
			if (resources != null) {
				List<IJavaElement> realJavaElements= new ArrayList<>();
				List<IResource> realResource= new ArrayList<>();
				ReorgUtils.splitIntoJavaElementsAndResources(resources, realJavaElements, realResource);
				for (IJavaElement element : realJavaElements) {
					if (!ReorgUtils.containsElementOrParent(elements, element))
						elements.add(element);
				}
				for (IResource element : realResource) {
					if (!ReorgUtils.containsElementOrParent(elements, element))
						elements.add(element);
				}
			}
			workingSet.setElements(elements.toArray(new IAdaptable[elements.size()]));
		}
		@Override
		public boolean canEnable(TransferData[] availableTypes) {
			return isAvailable(ResourceTransfer.getInstance(), availableTypes) ||
				isAvailable(JavaElementTransfer.getInstance(), availableTypes);
		}
		@Override
		public boolean canPasteOn(IJavaElement[] selectedJavaElements, IResource[] selectedResources, IWorkingSet[] selectedWorkingSets, List<?> selectedElements) throws JavaModelException {
			if (selectedResources.length != 0 || selectedJavaElements.length != 0 || selectedWorkingSets.length != 1)
				return false;
			IWorkingSet ws= selectedWorkingSets[0];
			return !IWorkingSetIDs.OTHERS.equals(ws.getId());
		}
	}

	private static class ProjectPaster extends Paster{

		protected ProjectPaster(Shell shell, Clipboard clipboard) {
			super(shell, clipboard);
		}

		@Override
		public boolean canEnable(TransferData[] availableDataTypes) {
			boolean resourceTransfer= isAvailable(ResourceTransfer.getInstance(), availableDataTypes);
			boolean javaElementTransfer= isAvailable(JavaElementTransfer.getInstance(), availableDataTypes);
			if (! javaElementTransfer)
				return canPasteSimpleProjects(availableDataTypes);
			if (! resourceTransfer)
				return canPasteJavaProjects(availableDataTypes);
			return canPasteJavaProjects(availableDataTypes) && canPasteSimpleProjects(availableDataTypes);
		}

		@Override
		public void paste(IJavaElement[] javaElements, IResource[] resources, IWorkingSet[] selectedWorkingSets, TransferData[] availableTypes) {
			pasteProjects(availableTypes);
		}

		private void pasteProjects(TransferData[] availableTypes) {
			pasteProjects(getProjectsToPaste(availableTypes));
		}

		private void pasteProjects(IProject[] projects){
			Shell shell= getShell();
			for (IProject project : projects) {
				new CopyProjectOperation(shell).copyProject(project);
			}
		}
		private IProject[] getProjectsToPaste(TransferData[] availableTypes) {
			IResource[] resources= getClipboardResources(availableTypes);
			IJavaElement[] javaElements= getClipboardJavaElements(availableTypes);
			Set<IResource> result= new HashSet<>();
			if (resources != null)
				result.addAll(Arrays.asList(resources));
			if (javaElements != null)
				result.addAll(Arrays.asList(ReorgUtils.getNotNulls(ReorgUtils.getResources(javaElements))));
			Assert.isTrue(result.size() > 0);
			return result.toArray(new IProject[result.size()]);
		}

		@Override
		public boolean canPasteOn(IJavaElement[] javaElements, IResource[] resources, IWorkingSet[] selectedWorkingSets, List<?> selectedElements) {
			return selectedWorkingSets.length == 0; // Can't paste on working sets here
		}

		private boolean canPasteJavaProjects(TransferData[] availableDataTypes) {
			IJavaElement[] javaElements= getClipboardJavaElements(availableDataTypes);
			return 	javaElements != null &&
					javaElements.length != 0 &&
					! ReorgUtils.hasElementsNotOfType(javaElements, IJavaElement.JAVA_PROJECT);
		}

		private boolean canPasteSimpleProjects(TransferData[] availableDataTypes) {
			IResource[] resources= getClipboardResources(availableDataTypes);
			if (resources == null || resources.length == 0) return false;
			for (IResource resource : resources) {
				if (resource.getType() != IResource.PROJECT || !((IProject) resource).isOpen()) {
					return false;
				}
			}
			return true;
		}
	}

	private static class FilePaster extends Paster{
		protected FilePaster(Shell shell, Clipboard clipboard) {
			super(shell, clipboard);
		}

		@Override
		public void paste(IJavaElement[] javaElements, IResource[] resources, IWorkingSet[] selectedWorkingSets, TransferData[] availableTypes) throws JavaModelException {
			String[] fileData= getClipboardFiles(availableTypes);
			if (fileData == null)
				return;

			IContainer container= getAsContainer(getTarget(javaElements, resources));
			if (container == null)
				return;

			new CopyFilesAndFoldersOperation(getShell()).copyFiles(fileData, container);
		}

		private Object getTarget(IJavaElement[] javaElements, IResource[] resources) {
			if (javaElements.length + resources.length == 1){
				if (javaElements.length == 1)
					return javaElements[0];
				else
					return resources[0];
			} else
				return getCommonParent(javaElements, resources);
		}

		@Override
		public boolean canPasteOn(IJavaElement[] javaElements, IResource[] resources, IWorkingSet[] selectedWorkingSets, List<?> selectedElements) throws JavaModelException {
			Object target= getTarget(javaElements, resources);
			return target != null && canPasteFilesOn(getAsContainer(target)) && selectedWorkingSets.length == 0;
		}

		@Override
		public boolean canEnable(TransferData[] availableDataTypes) {
			return isAvailable(FileTransfer.getInstance(), availableDataTypes);
		}

		private boolean canPasteFilesOn(Object target) {
			boolean isPackageFragment= target instanceof IPackageFragment;
			boolean isJavaProject= target instanceof IJavaProject;
			boolean isPackageFragmentRoot= target instanceof IPackageFragmentRoot;
			boolean isContainer= target instanceof IContainer;

			if (!isPackageFragment && !isJavaProject && !isPackageFragmentRoot && !isContainer)
				return false;

			if (isContainer) {
				if (target instanceof IProject)
					return ((IProject)target).isOpen();

				return true;
			} else {
				if (isJavaProject && !((IJavaProject) target).getProject().isOpen())
					return false;

				IJavaElement element= (IJavaElement)target;
				return !element.isReadOnly();
			}
		}

		private IContainer getAsContainer(Object target) throws JavaModelException{
			if (target == null)
				return null;
			if (target instanceof IContainer)
				return (IContainer)target;
			if (target instanceof IFile)
				return ((IFile)target).getParent();
			return getAsContainer(((IJavaElement)target).getCorrespondingResource());
		}

		private String[] getClipboardFiles(TransferData[] availableDataTypes) {
			Transfer transfer= FileTransfer.getInstance();
			if (isAvailable(transfer, availableDataTypes)) {
				return (String[])getContents(getClipboard(), transfer, getShell());
			}
			return null;
		}
		private Object getCommonParent(IJavaElement[] javaElements, IResource[] resources) {
			return new ParentChecker(resources, javaElements).getCommonParent();
		}
	}
	private static class JavaElementAndResourcePaster extends Paster {

		protected JavaElementAndResourcePaster(Shell shell, Clipboard clipboard) {
			super(shell, clipboard);
		}

		private TransferData[] fAvailableTypes;

		@Override
		public void paste(IJavaElement[] javaElements, IResource[] resources, IWorkingSet[] selectedWorkingSets, TransferData[] availableTypes) throws JavaModelException, InterruptedException, InvocationTargetException{
			IResource[] clipboardResources= getClipboardResources(availableTypes);
			if (clipboardResources == null)
				clipboardResources= new IResource[0];
			IJavaElement[] clipboardJavaElements= getClipboardJavaElements(availableTypes);
			if (clipboardJavaElements == null)
				clipboardJavaElements= new IJavaElement[0];

			Object destination= getTarget(javaElements, resources);
			Assert.isNotNull(destination);
			Assert.isLegal(clipboardResources.length + clipboardJavaElements.length > 0);
			ReorgCopyStarter.create(clipboardJavaElements, clipboardResources, ReorgDestinationFactory.createDestination(destination)).run(getShell());
		}

		private Object getTarget(IJavaElement[] javaElements, IResource[] resources) {
			if (javaElements.length + resources.length == 1){
				if (javaElements.length == 1)
					return javaElements[0];
				else
					return resources[0];
			} else
				return getCommonParent(javaElements, resources);
		}

		private Object getCommonParent(IJavaElement[] javaElements, IResource[] resources) {
			return new ParentChecker(resources, javaElements).getCommonParent();
		}

		@Override
		public boolean canPasteOn(IJavaElement[] javaElements, IResource[] resources, IWorkingSet[] selectedWorkingSets, List<?> selectedElements) throws JavaModelException {
			if (selectedWorkingSets.length != 0)
				return false;
			IResource[] clipboardResources= getClipboardResources(fAvailableTypes);
			if (clipboardResources == null)
				clipboardResources= new IResource[0];
			IJavaElement[] clipboardJavaElements= getClipboardJavaElements(fAvailableTypes);
			if (clipboardJavaElements == null)
				clipboardJavaElements= new IJavaElement[0];
			Object destination= getTarget(javaElements, resources);
			return ReorgCopyStarter.create(clipboardJavaElements, clipboardResources, ReorgDestinationFactory.createDestination(destination)) != null;
		}

		@Override
		public boolean canEnable(TransferData[] availableTypes) {
			fAvailableTypes= availableTypes;
			return isAvailable(JavaElementTransfer.getInstance(), availableTypes) || isAvailable(ResourceTransfer.getInstance(), availableTypes);
		}
	}

	private static class TypedSourcePaster extends Paster{

		protected TypedSourcePaster(Shell shell, Clipboard clipboard) {
			super(shell, clipboard);
		}
		private TransferData[] fAvailableTypes;

		@Override
		public boolean canEnable(TransferData[] availableTypes) {
			fAvailableTypes= availableTypes;
			return isAvailable(TypedSourceTransfer.getInstance(), availableTypes);
		}

		@Override
		public boolean canPasteOn(IJavaElement[] selectedJavaElements, IResource[] selectedResources, IWorkingSet[] selectedWorkingSets, List<?> selectedElements) throws JavaModelException {
			if (selectedResources.length != 0 || selectedWorkingSets.length != 0)
				return false;
			TypedSource[] typedSources= getClipboardTypedSources(fAvailableTypes);
			Object destination= getTarget(selectedJavaElements, selectedResources);
			if (destination instanceof IJavaElement)
				return ReorgTypedSourcePasteStarter.create(typedSources, (IJavaElement)destination) != null;
			return false;
		}

		@Override
		public void paste(IJavaElement[] selectedJavaElements, IResource[] selectedResources, IWorkingSet[] selectedWorkingSets, TransferData[] availableTypes) throws JavaModelException, InterruptedException, InvocationTargetException {
			TypedSource[] typedSources= getClipboardTypedSources(availableTypes);
			IJavaElement destination= getTarget(selectedJavaElements, selectedResources);
			ReorgTypedSourcePasteStarter.create(typedSources, destination).run(getShell());
		}

		private static IJavaElement getTarget(IJavaElement[] selectedJavaElements, IResource[] selectedResources) {
			Assert.isTrue(selectedResources.length == 0);
			if (selectedJavaElements.length == 1)
				return getAsTypeOrCu(selectedJavaElements[0]);
			Object parent= new ParentChecker(selectedResources, selectedJavaElements).getCommonParent();
			if (parent instanceof IJavaElement)
				return getAsTypeOrCu((IJavaElement)parent);
			return null;
		}
		private static IJavaElement getAsTypeOrCu(IJavaElement element) {
			//try to get type first
			if (element.getElementType() == IJavaElement.COMPILATION_UNIT || element.getElementType() == IJavaElement.TYPE)
				return element;
			IJavaElement ancestorType= element.getAncestor(IJavaElement.TYPE);
			if (ancestorType != null)
				return ancestorType;
			return ReorgUtils.getCompilationUnit(element);
		}
		private static class ReorgTypedSourcePasteStarter {

			private final PasteTypedSourcesRefactoring fPasteRefactoring;

			private ReorgTypedSourcePasteStarter(PasteTypedSourcesRefactoring pasteRefactoring) {
				Assert.isNotNull(pasteRefactoring);
				fPasteRefactoring= pasteRefactoring;
			}

			public static ReorgTypedSourcePasteStarter create(TypedSource[] typedSources, IJavaElement destination) {
				Assert.isNotNull(typedSources);
				Assert.isNotNull(destination);
				PasteTypedSourcesRefactoring pasteRefactoring= PasteTypedSourcesRefactoring.create(typedSources);
				if (pasteRefactoring == null)
					return null;
				if (! pasteRefactoring.setDestination(destination).isOK())
					return null;
				return new ReorgTypedSourcePasteStarter(pasteRefactoring);
			}

			public void run(Shell parent) throws InterruptedException, InvocationTargetException {
				IRunnableContext context= new ProgressMonitorDialog(parent);
				new RefactoringExecutionHelper(fPasteRefactoring, RefactoringCore.getConditionCheckingFailedSeverity(), RefactoringSaveHelper.SAVE_NOTHING, parent, context).perform(false, false);
			}
		}
		private static class PasteTypedSourcesRefactoring extends Refactoring {

			private final TypedSource[] fSources;
			private IJavaElement fDestination;

			static PasteTypedSourcesRefactoring create(TypedSource[] sources){
				if (! isAvailable(sources))
					return null;
				return new PasteTypedSourcesRefactoring(sources);
			}
			public RefactoringStatus setDestination(IJavaElement destination) {
				fDestination= destination;
				if (ReorgUtils.getCompilationUnit(destination) == null)
					return RefactoringStatus.createFatalErrorStatus(ReorgMessages.PasteAction_wrong_destination);
				if (! destination.exists())
					return RefactoringStatus.createFatalErrorStatus(ReorgMessages.PasteAction_element_doesnot_exist);
				if (! canPasteAll(destination))
					return RefactoringStatus.createFatalErrorStatus(ReorgMessages.PasteAction_invalid_destination);
				return new RefactoringStatus();
			}
			private boolean canPasteAll(IJavaElement destination) {
				for (TypedSource source : fSources) {
					if (!canPaste(source.getType(), destination)) {
						return false;
					}
				}
				return true;
			}
			private static boolean canPaste(int elementType, IJavaElement destination) {
				IType ancestorType= getAncestorType(destination);
				if (ancestorType != null)
					return canPasteToType(elementType);
				return canPasteToCu(elementType);
			}
			private static boolean canPasteToType(int elementType) {
				return 	elementType == IJavaElement.TYPE ||
						elementType == IJavaElement.FIELD ||
						elementType == IJavaElement.INITIALIZER ||
						elementType == IJavaElement.METHOD;
			}
			private static boolean canPasteToCu(int elementType) {
				return	elementType == IJavaElement.PACKAGE_DECLARATION ||
						elementType == IJavaElement.TYPE ||
						elementType == IJavaElement.IMPORT_DECLARATION;
			}
			PasteTypedSourcesRefactoring(TypedSource[] sources){
				Assert.isNotNull(sources);
				Assert.isTrue(sources.length != 0);
				fSources= sources;
			}

			private static boolean isAvailable(TypedSource[] sources) {
				return sources != null && sources.length > 0;
			}

			@Override
			public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException {
				return new RefactoringStatus();
			}

			@Override
			public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreException {
				RefactoringStatus result= Checks.validateModifiesFiles(
					ResourceUtil.getFiles(new ICompilationUnit[]{getDestinationCu()}), getValidationContext(), pm);
				return result;
			}

			@Override
			public Change createChange(IProgressMonitor pm) throws CoreException {
				ASTParser p= ASTParser.newParser(IASTSharedValues.SHARED_AST_LEVEL);
				p.setSource(getDestinationCu());
				CompilationUnit cuNode= (CompilationUnit) p.createAST(pm);
				ASTRewrite rewrite= ASTRewrite.create(cuNode.getAST());
				TypedSource source= null;
				for (int i= fSources.length - 1; i >= 0; i--) {
					source= fSources[i];
					final ASTNode destination= getDestinationNodeForSourceElement(fDestination, source.getType(), cuNode);
					if (destination != null) {
						if (destination instanceof CompilationUnit)
							insertToCu(rewrite, createNewNodeToInsertToCu(source, rewrite), (CompilationUnit) destination);
						else if (destination instanceof AbstractTypeDeclaration)
							insertToType(rewrite, createNewNodeToInsertToType(source, rewrite), (AbstractTypeDeclaration) destination);
					}
				}
				final CompilationUnitChange result= new CompilationUnitChange(ReorgMessages.PasteAction_change_name, getDestinationCu());
				try {
					ITextFileBuffer buffer= RefactoringFileBuffers.acquire(getDestinationCu());
					TextEdit rootEdit= rewrite.rewriteAST(buffer.getDocument(), fDestination.getJavaProject().getOptions(true));
					if (getDestinationCu().isWorkingCopy())
						result.setSaveMode(TextFileChange.LEAVE_DIRTY);
					TextChangeCompatibility.addTextEdit(result, ReorgMessages.PasteAction_edit_name, rootEdit);
				} finally {
					RefactoringFileBuffers.release(getDestinationCu());
				}
				return result;
			}

			private static void insertToType(ASTRewrite rewrite, ASTNode node, AbstractTypeDeclaration typeDeclaration) {
				switch (node.getNodeType()) {
					case ASTNode.ANNOTATION_TYPE_DECLARATION:
					case ASTNode.ENUM_DECLARATION:
					case ASTNode.TYPE_DECLARATION:
					case ASTNode.METHOD_DECLARATION:
					case ASTNode.FIELD_DECLARATION:
					case ASTNode.INITIALIZER:
						rewrite.getListRewrite(typeDeclaration, typeDeclaration.getBodyDeclarationsProperty()).insertAt(node, BodyDeclarationRewrite.getInsertionIndex((BodyDeclaration) node, typeDeclaration.bodyDeclarations()), null);
						break;
					default:
						Assert.isTrue(false, String.valueOf(node.getNodeType()));
				}
			}

			private static void insertToCu(ASTRewrite rewrite, ASTNode node, CompilationUnit cuNode) {
				switch (node.getNodeType()) {
					case ASTNode.TYPE_DECLARATION:
					case ASTNode.ENUM_DECLARATION:
					case ASTNode.ANNOTATION_TYPE_DECLARATION:
						rewrite.getListRewrite(cuNode, CompilationUnit.TYPES_PROPERTY).insertAt(node, BodyDeclarationRewrite.getInsertionIndex((AbstractTypeDeclaration) node, cuNode.types()), null);
						break;
					case ASTNode.IMPORT_DECLARATION:
						rewrite.getListRewrite(cuNode, CompilationUnit.IMPORTS_PROPERTY).insertLast(node, null);
						break;
					case ASTNode.PACKAGE_DECLARATION:
						// only insert if none exists
						if (cuNode.getPackage() == null)
							rewrite.set(cuNode, CompilationUnit.PACKAGE_PROPERTY, node, null);
						break;
					default:
						Assert.isTrue(false, String.valueOf(node.getNodeType()));
				}
			}

			/**
			 * @param destination the destination element
			 * @param kind the type of the source to paste
			 * @param unit the parsed CU
			 * @return an AbstractTypeDeclaration, a CompilationUnit, or null
			 * @throws JavaModelException if something fails
			 */
			private ASTNode getDestinationNodeForSourceElement(IJavaElement destination, int kind, CompilationUnit unit) throws JavaModelException {
				final IType ancestor= getAncestorType(destination);
				if (ancestor != null)
					return ASTNodeSearchUtil.getAbstractTypeDeclarationNode(ancestor, unit);
				if (kind == IJavaElement.TYPE || kind == IJavaElement.PACKAGE_DECLARATION || kind == IJavaElement.IMPORT_DECLARATION || kind == IJavaElement.IMPORT_CONTAINER)
					return unit;
				return null;
			}

			private static IType getAncestorType(IJavaElement destinationElement) {
				return destinationElement.getElementType() == IJavaElement.TYPE ? (IType)destinationElement: (IType)destinationElement.getAncestor(IJavaElement.TYPE);
			}
			private ASTNode createNewNodeToInsertToCu(TypedSource source, ASTRewrite rewrite) {
				switch(source.getType()){
					case IJavaElement.TYPE:
						return rewrite.createStringPlaceholder(source.getSource(), ASTNode.TYPE_DECLARATION);
					case IJavaElement.PACKAGE_DECLARATION:
						return rewrite.createStringPlaceholder(source.getSource(), ASTNode.PACKAGE_DECLARATION);
					case IJavaElement.IMPORT_DECLARATION:
						return rewrite.createStringPlaceholder(source.getSource(), ASTNode.IMPORT_DECLARATION);
					default: Assert.isTrue(false, String.valueOf(source.getType()));
						return null;
				}
			}

			private ASTNode createNewNodeToInsertToType(TypedSource source, ASTRewrite rewrite) {
				switch(source.getType()){
					case IJavaElement.TYPE:
						return rewrite.createStringPlaceholder(source.getSource(), ASTNode.TYPE_DECLARATION);
					case IJavaElement.METHOD:
						return rewrite.createStringPlaceholder(source.getSource(), ASTNode.METHOD_DECLARATION);
					case IJavaElement.FIELD:
						return rewrite.createStringPlaceholder(source.getSource(), ASTNode.FIELD_DECLARATION);
					case IJavaElement.INITIALIZER:
						return rewrite.createStringPlaceholder(source.getSource(), ASTNode.INITIALIZER);
					default: Assert.isTrue(false);
						return null;
				}
			}

			private ICompilationUnit getDestinationCu() {
				return ReorgUtils.getCompilationUnit(fDestination);
			}

			@Override
			public String getName() {
				return ReorgMessages.PasteAction_name;
			}
		}
	}
}
