/*******************************************************************************
 * Copyright (c) 2000, 2018 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.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.Iterator;
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.resources.IWorkspaceRunnable;

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.refactoring.CompilationUnitChange;

import org.eclipse.jdt.internal.core.manipulation.util.BasicElementLabels;
import org.eclipse.jdt.internal.core.manipulation.util.Strings;
import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility;
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.CodeGeneration;
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= JavaPlugin.getDefault().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(new Runnable() {
			@Override
			public void run() {
				result[0]= clipboard.getContents(transfer);
			}
		});
		return result[0];
	}

	private static boolean isAvailable(Transfer transfer, TransferData[] availableDataTypes) {
		for (int i= 0; i < availableDataTypes.length; i++) {
			if (transfer.isSupportedType(availableDataTypes[i])) 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);
			Paster[] pasters= createEnabledPasters(availableTypes, clipboard);
			for (int i= 0; i < pasters.length; i++) {
				try {
					if (pasters[i].canPasteOn(javaElements, resources, workingSets, elements)) {
						pasters[i].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 (Iterator<AbstractTypeDeclaration> iter= types.iterator(); iter.hasNext(); ) {
					AbstractTypeDeclaration type= iter.next();
					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.size() != 0) {
				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 :
					IPackageFragmentRoot[] packageFragmentRoots= ((IJavaProject) destination).getPackageFragmentRoots();
					for (int i= 0; i < packageFragmentRoots.length; i++) {
						packageFragmentRoot= packageFragmentRoots[i];
						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(new IWorkspaceRunnable() {
							@Override
							public void run(IProgressMonitor pm) throws CoreException {
								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 (int i= 0; i < fParsedCus.length; i++) {
									if (pm.isCanceled())
										break;
									ICompilationUnit cu= pasteCU(fParsedCus[i], 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 e) {
						JavaPlugin.log(e);
					} catch (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) "" : new Integer(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 e) {
				JavaPlugin.log(e);
				return null;
			} catch (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;

			IExecutionEnvironment[] ees= eeManager.getExecutionEnvironments();
			outer: for (int j= 0; j < ees.length; j++) {
				IExecutionEnvironment ee= ees[j];
				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);
					IVMInstall[] compatibleVMs= ee.getCompatibleVMs();
					for (int i= 0; i < compatibleVMs.length; i++) {
						vm= compatibleVMs[i];
						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;
						}
					}
				}
			}

			IVMInstallType[] vmTypes= JavaRuntime.getVMInstallTypes();
			for (int i= 0; i < vmTypes.length; i++) {
				IVMInstall[] vms= vmTypes[i].getVMInstalls();
				for (int j= 0; j < vms.length; j++) {
					IVMInstall vm= vms[j];
					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 (int i= 0; i < javaElements.length; i++) {
					if (!ReorgUtils.containsElementOrParent(elements, javaElements[i]))
						elements.add(javaElements[i]);
				}
			}
			IResource[] resources= getClipboardResources(availableTypes);
			if (resources != null) {
				List<IJavaElement> realJavaElements= new ArrayList<>();
				List<IResource> realResource= new ArrayList<>();
				ReorgUtils.splitIntoJavaElementsAndResources(resources, realJavaElements, realResource);
				for (Iterator<IJavaElement> iter= realJavaElements.iterator(); iter.hasNext();) {
					IJavaElement element= iter.next();
					if (!ReorgUtils.containsElementOrParent(elements, element))
						elements.add(element);
				}
				for (Iterator<IResource> iter= realResource.iterator(); iter.hasNext();) {
					IResource element= iter.next();
					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 (int i = 0; i < projects.length; i++) {
				new CopyProjectOperation(shell).copyProject(projects[i]);
			}
		}
		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 (int i= 0; i < resources.length; i++) {
				if (resources[i].getType() != IResource.PROJECT || ! ((IProject)resources[i]).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 (int i= 0; i < fSources.length; i++) {
					if (! canPaste(fSources[i].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());
				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;
			}
		}
    }
}
