/*******************************************************************************
 * Copyright (c) 2000, 2008 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.wst.jsdt.internal.corext.refactoring.structure;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
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.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.TextUtilities;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.RefactoringStatusEntry;
import org.eclipse.ltk.core.refactoring.TextChange;
import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
import org.eclipse.ltk.core.refactoring.participants.MoveProcessor;
import org.eclipse.ltk.core.refactoring.participants.RefactoringArguments;
import org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant;
import org.eclipse.ltk.core.refactoring.participants.SharableParticipants;
import org.eclipse.text.edits.MultiTextEdit;
import org.eclipse.text.edits.RangeMarker;
import org.eclipse.text.edits.TextEdit;
import org.eclipse.text.edits.TextEditGroup;
import org.eclipse.text.edits.TextEditProcessor;
import org.eclipse.wst.jsdt.core.Flags;
import org.eclipse.wst.jsdt.core.IField;
import org.eclipse.wst.jsdt.core.IFunction;
import org.eclipse.wst.jsdt.core.IJavaScriptElement;
import org.eclipse.wst.jsdt.core.IJavaScriptProject;
import org.eclipse.wst.jsdt.core.IJavaScriptUnit;
import org.eclipse.wst.jsdt.core.IType;
import org.eclipse.wst.jsdt.core.ITypeHierarchy;
import org.eclipse.wst.jsdt.core.JavaScriptCore;
import org.eclipse.wst.jsdt.core.JavaScriptModelException;
import org.eclipse.wst.jsdt.core.dom.AST;
import org.eclipse.wst.jsdt.core.dom.ASTNode;
import org.eclipse.wst.jsdt.core.dom.ASTVisitor;
import org.eclipse.wst.jsdt.core.dom.AbstractTypeDeclaration;
import org.eclipse.wst.jsdt.core.dom.AnonymousClassDeclaration;
import org.eclipse.wst.jsdt.core.dom.Assignment;
import org.eclipse.wst.jsdt.core.dom.Block;
import org.eclipse.wst.jsdt.core.dom.BodyDeclaration;
import org.eclipse.wst.jsdt.core.dom.ClassInstanceCreation;
import org.eclipse.wst.jsdt.core.dom.Expression;
import org.eclipse.wst.jsdt.core.dom.FieldAccess;
import org.eclipse.wst.jsdt.core.dom.FunctionDeclaration;
import org.eclipse.wst.jsdt.core.dom.FunctionInvocation;
import org.eclipse.wst.jsdt.core.dom.FunctionRef;
import org.eclipse.wst.jsdt.core.dom.FunctionRefParameter;
import org.eclipse.wst.jsdt.core.dom.IBinding;
import org.eclipse.wst.jsdt.core.dom.IFunctionBinding;
import org.eclipse.wst.jsdt.core.dom.ITypeBinding;
import org.eclipse.wst.jsdt.core.dom.IVariableBinding;
import org.eclipse.wst.jsdt.core.dom.JSdoc;
import org.eclipse.wst.jsdt.core.dom.Modifier;
import org.eclipse.wst.jsdt.core.dom.Name;
import org.eclipse.wst.jsdt.core.dom.NullLiteral;
import org.eclipse.wst.jsdt.core.dom.PostfixExpression;
import org.eclipse.wst.jsdt.core.dom.PrefixExpression;
import org.eclipse.wst.jsdt.core.dom.PrimitiveType;
import org.eclipse.wst.jsdt.core.dom.QualifiedName;
import org.eclipse.wst.jsdt.core.dom.SimpleName;
import org.eclipse.wst.jsdt.core.dom.SingleVariableDeclaration;
import org.eclipse.wst.jsdt.core.dom.SuperFieldAccess;
import org.eclipse.wst.jsdt.core.dom.SuperMethodInvocation;
import org.eclipse.wst.jsdt.core.dom.TagElement;
import org.eclipse.wst.jsdt.core.dom.ThisExpression;
import org.eclipse.wst.jsdt.core.dom.TypeDeclaration;
import org.eclipse.wst.jsdt.core.dom.TypeParameter;
import org.eclipse.wst.jsdt.core.dom.VariableDeclaration;
import org.eclipse.wst.jsdt.core.dom.rewrite.ASTRewrite;
import org.eclipse.wst.jsdt.core.dom.rewrite.ListRewrite;
import org.eclipse.wst.jsdt.core.refactoring.IJavaScriptRefactorings;
import org.eclipse.wst.jsdt.core.refactoring.descriptors.JavaScriptRefactoringDescriptor;
import org.eclipse.wst.jsdt.core.search.IJavaScriptSearchConstants;
import org.eclipse.wst.jsdt.core.search.SearchMatch;
import org.eclipse.wst.jsdt.core.search.SearchPattern;
import org.eclipse.wst.jsdt.internal.corext.SourceRange;
import org.eclipse.wst.jsdt.internal.corext.codemanipulation.CodeGenerationSettings;
import org.eclipse.wst.jsdt.internal.corext.codemanipulation.GetterSetterUtil;
import org.eclipse.wst.jsdt.internal.corext.codemanipulation.StubUtility;
import org.eclipse.wst.jsdt.internal.corext.dom.ASTNodeFactory;
import org.eclipse.wst.jsdt.internal.corext.dom.ASTNodes;
import org.eclipse.wst.jsdt.internal.corext.dom.Bindings;
import org.eclipse.wst.jsdt.internal.corext.dom.ModifierRewrite;
import org.eclipse.wst.jsdt.internal.corext.dom.ScopeAnalyzer;
import org.eclipse.wst.jsdt.internal.corext.refactoring.Checks;
import org.eclipse.wst.jsdt.internal.corext.refactoring.JDTRefactoringDescriptor;
import org.eclipse.wst.jsdt.internal.corext.refactoring.JDTRefactoringDescriptorComment;
import org.eclipse.wst.jsdt.internal.corext.refactoring.JavaRefactoringArguments;
import org.eclipse.wst.jsdt.internal.corext.refactoring.RefactoringCoreMessages;
import org.eclipse.wst.jsdt.internal.corext.refactoring.RefactoringSearchEngine2;
import org.eclipse.wst.jsdt.internal.corext.refactoring.SearchResultGroup;
import org.eclipse.wst.jsdt.internal.corext.refactoring.base.JavaStatusContext;
import org.eclipse.wst.jsdt.internal.corext.refactoring.changes.DynamicValidationRefactoringChange;
import org.eclipse.wst.jsdt.internal.corext.refactoring.code.ScriptableRefactoring;
import org.eclipse.wst.jsdt.internal.corext.refactoring.delegates.DelegateMethodCreator;
import org.eclipse.wst.jsdt.internal.corext.refactoring.structure.MemberVisibilityAdjustor.IVisibilityAdjustment;
import org.eclipse.wst.jsdt.internal.corext.refactoring.tagging.ICommentProvider;
import org.eclipse.wst.jsdt.internal.corext.refactoring.tagging.IDelegateUpdating;
import org.eclipse.wst.jsdt.internal.corext.refactoring.tagging.IScriptableRefactoring;
import org.eclipse.wst.jsdt.internal.corext.refactoring.util.JavadocUtil;
import org.eclipse.wst.jsdt.internal.corext.refactoring.util.ResourceUtil;
import org.eclipse.wst.jsdt.internal.corext.refactoring.util.TextChangeManager;
import org.eclipse.wst.jsdt.internal.corext.util.JavaModelUtil;
import org.eclipse.wst.jsdt.internal.corext.util.JdtFlags;
import org.eclipse.wst.jsdt.internal.corext.util.Messages;
import org.eclipse.wst.jsdt.internal.corext.util.SearchUtils;
import org.eclipse.wst.jsdt.internal.corext.util.Strings;
import org.eclipse.wst.jsdt.internal.ui.JavaScriptPlugin;
import org.eclipse.wst.jsdt.internal.ui.preferences.JavaPreferencesSettings;
import org.eclipse.wst.jsdt.internal.ui.viewsupport.BindingLabelProvider;
import org.eclipse.wst.jsdt.ui.JavaScriptElementLabels;

/**
 * Refactoring processor to move instance methods.
 */
public final class MoveInstanceMethodProcessor extends MoveProcessor implements IScriptableRefactoring, IDelegateUpdating, ICommentProvider {

	/**
	 * AST visitor to find references to parameters occurring in anonymous
	 * classes of a method body.
	 */
	public final class AnonymousClassReferenceFinder extends AstNodeFinder {

		/** The anonymous class nesting counter */
		protected int fAnonymousClass= 0;

		/** The declaring type of the method declaration */
		protected final ITypeBinding fDeclaringType;

		/**
		 * Creates a new anonymous class reference finder.
		 * 
		 * @param declaration
		 *            the method declaration to search for references
		 */
		public AnonymousClassReferenceFinder(final FunctionDeclaration declaration) {
			fDeclaringType= declaration.resolveBinding().getDeclaringClass();
		}

		public final void endVisit(final AnonymousClassDeclaration node) {
			Assert.isNotNull(node);
			if (fAnonymousClass > 0)
				fAnonymousClass--;
			super.endVisit(node);
		}

		public final boolean visit(final AnonymousClassDeclaration node) {
			Assert.isNotNull(node);
			fAnonymousClass++;
			return super.visit(node);
		}

		public final boolean visit(final FunctionInvocation node) {
			Assert.isNotNull(node);
			if (fAnonymousClass > 0) {
				final IFunctionBinding binding= node.resolveMethodBinding();
				if (binding != null) {
					if (node.getExpression() == null && !Modifier.isStatic(binding.getModifiers()))
						fResult.add(node.getName());
				}
			}
			return true;
		}

		public boolean visit(final SimpleName node) {
			Assert.isNotNull(node);
			if (fAnonymousClass > 0) {
				if (!(node.getParent() instanceof FieldAccess)) {
					final IBinding binding= node.resolveBinding();
					if (binding instanceof IVariableBinding) {
						final IVariableBinding variable= (IVariableBinding) binding;
						final ITypeBinding declaring= variable.getDeclaringClass();
						if (declaring != null && Bindings.equals(declaring, fDeclaringType))
							fResult.add(node);
					}
				}
			}
			return false;
		}
	}

	/**
	 * Partial implementation of an ast node finder.
	 */
	protected static class AstNodeFinder extends ASTVisitor {

		/** The found ast nodes */
		protected final Set fResult= new HashSet();

		/** The status of the find operation */
		protected final RefactoringStatus fStatus= new RefactoringStatus();

		/**
		 * Returns the result set.
		 * 
		 * @return the result set
		 */
		public final Set getResult() {
			return fResult;
		}

		/**
		 * Returns the status of the find operation.
		 * 
		 * @return the status of the operation
		 */
		public final RefactoringStatus getStatus() {
			return fStatus;
		}
	}

	class DelegateInstanceMethodCreator extends DelegateMethodCreator {

		private Map fAdjustments;

		private boolean fNeededInsertion;

		private Map fRewrites;

		public DelegateInstanceMethodCreator(Map adjustments, Map rewrites) {
			super();
			fAdjustments= adjustments;
			fRewrites= rewrites;
		}

		protected ASTNode createBody(BodyDeclaration bd) throws JavaScriptModelException {
			FunctionDeclaration methodDeclaration= (FunctionDeclaration) bd;
			final FunctionInvocation invocation= getAst().newFunctionInvocation();
			invocation.setName(getAst().newSimpleName(getNewElementName()));
			invocation.setExpression(createSimpleTargetAccessExpression(methodDeclaration));
			fNeededInsertion= createArgumentList(methodDeclaration, invocation.arguments(), new VisibilityAdjustingArgumentFactory(getAst(), fRewrites, fAdjustments));
			final Block block= getAst().newBlock();
			block.statements().add(createMethodInvocation(methodDeclaration, invocation));
			if (!fSourceRewrite.getCu().equals(fTargetType.getJavaScriptUnit()))
				fSourceRewrite.getImportRemover().registerRemovedNode(methodDeclaration.getBody());
			return block;
		}

		protected ASTNode createDocReference(final BodyDeclaration declaration) throws JavaScriptModelException {
			return MoveInstanceMethodProcessor.this.createMethodReference((FunctionDeclaration) declaration, getAst());
		}

		protected boolean getNeededInsertion() {
			return fNeededInsertion;
		}
	}

	/**
	 * AST visitor to find 'this' references to enclosing instances.
	 */
	public final class EnclosingInstanceReferenceFinder extends AstNodeFinder {

		/** The list of enclosing types */
		private final List fEnclosingTypes= new ArrayList(3);

		/**
		 * Creates a new enclosing instance reference finder.
		 * 
		 * @param binding
		 *            the declaring type
		 */
		public EnclosingInstanceReferenceFinder(final ITypeBinding binding) {
			Assert.isNotNull(binding);
			ITypeBinding declaring= binding.getDeclaringClass();
			while (declaring != null) {
				fEnclosingTypes.add(declaring);
				declaring= declaring.getDeclaringClass();
			}
		}

		public final boolean visit(final SimpleName node) {
			Assert.isNotNull(node);
			final IBinding binding= node.resolveBinding();
			ITypeBinding declaring= null;
			if (binding instanceof IVariableBinding) {
				final IVariableBinding variable= (IVariableBinding) binding;
				if (Flags.isStatic(variable.getModifiers()))
					return false;
				declaring= variable.getDeclaringClass();
			} else if (binding instanceof IFunctionBinding) {
				final IFunctionBinding method= (IFunctionBinding) binding;
				if (Flags.isStatic(method.getModifiers()))
					return false;
				declaring= method.getDeclaringClass();
			}
			if (declaring != null) {
				ITypeBinding enclosing= null;
				for (final Iterator iterator= fEnclosingTypes.iterator(); iterator.hasNext();) {
					enclosing= (ITypeBinding) iterator.next();
					if (Bindings.equals(enclosing, declaring)) {
						fStatus.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_refers_enclosing_instances, JavaStatusContext.create(fMethod.getJavaScriptUnit(), node)));
						fResult.add(node);
						break;
					}
				}
			}
			return false;
		}

		public final boolean visit(final ThisExpression node) {
			Assert.isNotNull(node);
			if (node.getQualifier() != null) {
				fStatus.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_refers_enclosing_instances, JavaStatusContext.create(fMethod.getJavaScriptUnit(), node)));
				fResult.add(node);
			}
			return false;
		}
	}

	/**
	 * AST visitor to find references to type variables or generic types.
	 */
	public final class GenericReferenceFinder extends AstNodeFinder {

		/** The type parameter binding keys */
		protected final Set fBindings= new HashSet();

		/**
		 * Creates a new generic reference finder.
		 * 
		 * @param declaration
		 *            the method declaration
		 */
		public GenericReferenceFinder(final FunctionDeclaration declaration) {
			Assert.isNotNull(declaration);
			ITypeBinding binding= null;
			TypeParameter parameter= null;
			for (final Iterator iterator= declaration.typeParameters().iterator(); iterator.hasNext();) {
				parameter= (TypeParameter) iterator.next();
				binding= parameter.resolveBinding();
				if (binding != null)
					fBindings.add(binding.getKey());
			}
		}

		/*
		 * @see org.eclipse.wst.jsdt.core.dom.ASTVisitor#visit(org.eclipse.wst.jsdt.core.dom.SimpleName)
		 */
		public final boolean visit(final SimpleName node) {
			Assert.isNotNull(node);
			final IBinding binding= node.resolveBinding();
			if (binding instanceof ITypeBinding) {
				final ITypeBinding type= (ITypeBinding) binding;
				if (!fBindings.contains(type.getKey()) && type.isTypeVariable()) {
					fResult.add(node);
					fStatus.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_no_type_variables, JavaStatusContext.create(fMethod.getJavaScriptUnit(), node)));
					return false;
				}
			}
			return true;
		}
	}

	/**
	 * Factory for method argument declaration or expression nodes.
	 */
	protected static interface IArgumentFactory {

		/**
		 * Returns a argument node for the specified variable binding.
		 * 
		 * @param binding
		 *            the binding to create a argument node for
		 * @param last
		 *            <code>true</code> if the argument represented by this
		 *            node is the last one in its declaring method
		 * @return the corresponding node
		 * @throws JavaScriptModelException
		 *             if an error occurs
		 */
		public ASTNode getArgumentNode(IVariableBinding binding, boolean last) throws JavaScriptModelException;

		/**
		 * Returns a target node for the current target.
		 * 
		 * @return the corresponding node
		 * @throws JavaScriptModelException
		 *             if an error occurs
		 */
		public ASTNode getTargetNode() throws JavaScriptModelException;
	}

	/**
	 * AST visitor to rewrite the body of the moved method.
	 */
	public final class MethodBodyRewriter extends ASTVisitor {

		/** The anonymous class nesting counter */
		protected int fAnonymousClass= 0;

		/** The method declaration to rewrite */
		protected final FunctionDeclaration fDeclaration;

		/** The set of handled method invocations */
		protected final Set fMethodDeclarations= new HashSet();

		/** The source ast rewrite to use */
		protected final ASTRewrite fRewrite;

		/** The existing static imports */
		protected final Set fStaticImports= new HashSet();

		/** The refactoring status */
		protected final RefactoringStatus fStatus= new RefactoringStatus();

		/** The target compilation unit rewrite to use */
		protected final CompilationUnitRewrite fTargetRewrite;

		/**
		 * Creates a new method body rewriter.
		 * 
		 * @param targetRewrite
		 *            the target compilation unit rewrite to use
		 * @param rewrite
		 *            the source ast rewrite to use
		 * @param sourceDeclaration
		 *            the source method declaration
		 */
		public MethodBodyRewriter(final CompilationUnitRewrite targetRewrite, final ASTRewrite rewrite, final FunctionDeclaration sourceDeclaration) {
			Assert.isNotNull(targetRewrite);
			Assert.isNotNull(rewrite);
			Assert.isNotNull(sourceDeclaration);
			fTargetRewrite= targetRewrite;
			fRewrite= rewrite;
			fDeclaration= sourceDeclaration;
			fStaticImports.clear();
			ImportRewriteUtil.collectImports(fMethod.getJavaScriptProject(), sourceDeclaration, new HashSet(), fStaticImports, false);
		}

		public final void endVisit(final AnonymousClassDeclaration node) {
			Assert.isNotNull(node);
			if (fAnonymousClass > 0)
				fAnonymousClass--;
			super.endVisit(node);
		}

		public final boolean visit(final AnonymousClassDeclaration node) {
			Assert.isNotNull(node);
			fAnonymousClass++;
			return super.visit(node);
		}

		public final boolean visit(final ClassInstanceCreation node) {
			Assert.isNotNull(node);
			if (node.getParent() instanceof ClassInstanceCreation) {
				final AnonymousClassDeclaration declaration= node.getAnonymousClassDeclaration();
				if (declaration != null)
					visit(declaration);
				return false;
			}
			return super.visit(node);
		}

		public final boolean visit(final FieldAccess node) {
			Assert.isNotNull(node);
			final Expression expression= node.getExpression();
			final IVariableBinding variable= node.resolveFieldBinding();
			final AST ast= fRewrite.getAST();
			if (expression instanceof ThisExpression) {
				if (Bindings.equals(fTarget, variable)) {
					if (fAnonymousClass > 0) {
						final ThisExpression target= ast.newThisExpression();
						target.setQualifier(ast.newSimpleName(fTargetType.getElementName()));
						fRewrite.replace(node, target, null);
					} else
						fRewrite.replace(node, ast.newThisExpression(), null);
					return false;
				}
			}
			if (expression instanceof FieldAccess) {
				final FieldAccess access= (FieldAccess) expression;
				final IBinding binding= access.getName().resolveBinding();
				if ((access.getExpression() instanceof ThisExpression) && Bindings.equals(fTarget, binding)) {
					fRewrite.replace(node, ast.newSimpleName(node.getName().getIdentifier()), null);
					return false;
				}
			} else if (expression != null) {
				final IFunctionBinding method= fDeclaration.resolveBinding();
				if (variable != null && method != null && !JdtFlags.isStatic(variable) && Bindings.equals(method.getDeclaringClass(), variable.getDeclaringClass())) {
					fRewrite.replace(expression, ast.newSimpleName(fTargetName), null);
					return false;
				}
			}
			return true;
		}

		public final void visit(final List nodes) {
			Assert.isNotNull(nodes);
			ASTNode node= null;
			for (final Iterator iterator= nodes.iterator(); iterator.hasNext();) {
				node= (ASTNode) iterator.next();
				node.accept(this);
			}
		}

		public final boolean visit(final FunctionInvocation node) {
			Assert.isNotNull(node);
			final Expression expression= node.getExpression();
			final IFunctionBinding method= node.resolveMethodBinding();
			if (method != null) {
				final ASTRewrite rewrite= fRewrite;
				if (expression == null) {
					final AST ast= node.getAST();
					if (!JdtFlags.isStatic(method))
						rewrite.set(node, FunctionInvocation.EXPRESSION_PROPERTY, ast.newSimpleName(fTargetName), null);
					else
						rewrite.set(node, FunctionInvocation.EXPRESSION_PROPERTY, ast.newSimpleType(ast.newSimpleName(fMethod.getDeclaringType().getElementName())), null);
					return true;
				} else {
					if (expression instanceof FieldAccess) {
						final FieldAccess access= (FieldAccess) expression;
						if (Bindings.equals(access.resolveFieldBinding(), fTarget)) {
							rewrite.remove(expression, null);
							visit(node.arguments());
							return false;
						}
					} else if (expression instanceof Name) {
						final Name name= (Name) expression;
						if (Bindings.equals(name.resolveBinding(), fTarget)) {
							rewrite.remove(expression, null);
							visit(node.arguments());
							return false;
						}
					}
				}
			}
			return true;
		}

		public final boolean visit(final QualifiedName node) {
			Assert.isNotNull(node);
			IBinding binding= node.resolveBinding();
			if (binding instanceof ITypeBinding) {
				final ITypeBinding type= (ITypeBinding) binding;
				if (type.isClass() && type.getDeclaringClass() != null) {
					final String name= fTargetRewrite.getImportRewrite().addImport(type);
					if (name != null && name.length() > 0) {
						fRewrite.replace(node, ASTNodeFactory.newName(node.getAST(), name), null);
						return false;
					}
				}
			}
			binding= node.getQualifier().resolveBinding();
			if (Bindings.equals(binding, fTarget)) {
				fRewrite.replace(node, fRewrite.createCopyTarget(node.getName()), null);
				return false;
			}
			return true;
		}

		public final boolean visit(final SimpleName node) {
			Assert.isNotNull(node);
			final AST ast= node.getAST();
			final ASTRewrite rewrite= fRewrite;
			final IBinding binding= node.resolveBinding();
			if (binding instanceof ITypeBinding) {
				final ITypeBinding type= (ITypeBinding) binding;
				if (type.isClass() && type.getDeclaringClass() != null) {
					final String name= fTargetRewrite.getImportRewrite().addImport(type);
					if (name != null && name.length() > 0) {
						fRewrite.replace(node, ASTNodeFactory.newName(ast, name), null);
						return false;
					}
				}
			}
			if (Bindings.equals(binding, fTarget))
				if (fAnonymousClass > 0) {
					final ThisExpression target= ast.newThisExpression();
					target.setQualifier(ast.newSimpleName(fTargetType.getElementName()));
					fRewrite.replace(node, target, null);
				} else
					rewrite.replace(node, ast.newThisExpression(), null);
			else if (binding instanceof IVariableBinding) {
				final IVariableBinding variable= (IVariableBinding) binding;
				final IFunctionBinding method= fDeclaration.resolveBinding();
				final ITypeBinding declaring= variable.getDeclaringClass();
				if (method != null) {
					if (Bindings.equals(method.getDeclaringClass(), declaring)) {
						if (JdtFlags.isStatic(variable))
							rewrite.replace(node, ast.newQualifiedName(ASTNodeFactory.newName(ast, fTargetRewrite.getImportRewrite().addImport(declaring)), ast.newSimpleName(node.getFullyQualifiedName())), null);
						else {
							final FieldAccess access= ast.newFieldAccess();
							access.setExpression(ast.newSimpleName(fTargetName));
							access.setName(ast.newSimpleName(node.getFullyQualifiedName()));
							rewrite.replace(node, access, null);
						}
					} else if (!(node.getParent() instanceof QualifiedName) && JdtFlags.isStatic(variable) && !fStaticImports.contains(variable)) {
						rewrite.replace(node, ast.newQualifiedName(ASTNodeFactory.newName(ast, fTargetRewrite.getImportRewrite().addImport(declaring)), ast.newSimpleName(node.getFullyQualifiedName())), null);
					}
				}
			}
			return false;
		}

		public final boolean visit(final ThisExpression node) {
			Assert.isNotNull(node);
			fRewrite.replace(node, node.getAST().newSimpleName(fTargetName), null);
			return false;
		}
	}

	/**
	 * AST visitor to find read-only fields of the declaring class of 'this'.
	 */
	public static class ReadyOnlyFieldFinder extends ASTVisitor {

		/**
		 * Returns the field binding associated with this expression.
		 * 
		 * @param expression
		 *            the expression to get the field binding for
		 * @return the field binding, if the expression denotes a field access
		 *         or a field name, <code>null</code> otherwise
		 */
		protected static IVariableBinding getFieldBinding(final Expression expression) {
			Assert.isNotNull(expression);
			if (expression instanceof FieldAccess)
				return (IVariableBinding) ((FieldAccess) expression).getName().resolveBinding();
			if (expression instanceof Name) {
				final IBinding binding= ((Name) expression).resolveBinding();
				if (binding instanceof IVariableBinding) {
					final IVariableBinding variable= (IVariableBinding) binding;
					if (variable.isField())
						return variable;
				}
			}
			return null;
		}

		/**
		 * Is the specified name a qualified entity, e.g. preceded by 'this',
		 * 'super' or part of a method invocation?
		 * 
		 * @param name
		 *            the name to check
		 * @return <code>true</code> if this entity is qualified,
		 *         <code>false</code> otherwise
		 */
		protected static boolean isQualifiedEntity(final Name name) {
			Assert.isNotNull(name);
			final ASTNode parent= name.getParent();
			if ((parent instanceof QualifiedName && ((QualifiedName) parent).getName().equals(name)) || (parent instanceof FieldAccess && ((FieldAccess) parent).getName().equals(name)) || (parent instanceof SuperFieldAccess))
				return true;
			else if (parent instanceof FunctionInvocation) {
				final FunctionInvocation invocation= (FunctionInvocation) parent;
				return invocation.getExpression() != null && invocation.getName().equals(name);
			}
			return false;
		}

		/** The list of found bindings */
		protected final List fBindings= new LinkedList();

		/** The keys of the found bindings */
		protected final Set fFound= new HashSet();

		/** The keys of the written bindings */
		protected final Set fWritten= new HashSet();

		/**
		 * Creates a new read only field finder.
		 * 
		 * @param binding
		 *            The declaring class of the method declaring to find fields
		 *            for
		 */
		public ReadyOnlyFieldFinder(final ITypeBinding binding) {
			Assert.isNotNull(binding);
			final IVariableBinding[] bindings= binding.getDeclaredFields();
			IVariableBinding variable= null;
			for (int index= 0; index < bindings.length; index++) {
				variable= bindings[index];
				if (!variable.isSynthetic() && !fFound.contains(variable.getKey())) {
					fFound.add(variable.getKey());
					fBindings.add(variable);
				}
			}
		}

		/**
		 * Returns all fields of the declaring class plus the ones references in
		 * the visited method declaration.
		 * 
		 * @return all fields of the declaring class plus the references ones
		 */
		public final IVariableBinding[] getDeclaredFields() {
			final IVariableBinding[] result= new IVariableBinding[fBindings.size()];
			fBindings.toArray(result);
			return result;
		}

		/**
		 * Returns all fields of the declaring class which are not written by
		 * the visited method declaration.
		 * 
		 * @return all fields which are not written
		 */
		public final IVariableBinding[] getReadOnlyFields() {
			IVariableBinding binding= null;
			final List list= new LinkedList(fBindings);
			for (final Iterator iterator= list.iterator(); iterator.hasNext();) {
				binding= (IVariableBinding) iterator.next();
				if (fWritten.contains(binding.getKey()))
					iterator.remove();
			}
			final IVariableBinding[] result= new IVariableBinding[list.size()];
			list.toArray(result);
			return result;
		}

		public final boolean visit(final Assignment node) {
			Assert.isNotNull(node);
			final IVariableBinding binding= getFieldBinding(node.getLeftHandSide());
			if (binding != null)
				fWritten.add(binding.getKey());
			return true;
		}

		public final boolean visit(final FieldAccess node) {
			Assert.isNotNull(node);
			if (node.getExpression() instanceof ThisExpression) {
				final IVariableBinding binding= (IVariableBinding) node.getName().resolveBinding();
				if (binding != null) {
					final String key= binding.getKey();
					if (!fFound.contains(key)) {
						fFound.add(key);
						fBindings.add(binding);
					}
				}
			}
			return true;
		}

		public final boolean visit(final PostfixExpression node) {
			final IVariableBinding binding= getFieldBinding(node.getOperand());
			if (binding != null)
				fWritten.add(binding.getKey());
			return true;
		}

		public final boolean visit(final PrefixExpression node) {
			final IVariableBinding binding= getFieldBinding(node.getOperand());
			if (binding != null)
				fWritten.add(binding.getKey());
			return false;
		}

		public final boolean visit(final SimpleName node) {
			Assert.isNotNull(node);
			final IBinding binding= node.resolveBinding();
			if (binding != null)
				if (isFieldAccess(node) && !isQualifiedEntity(node)) {
					final IVariableBinding variable= (IVariableBinding) binding;
					final String key= variable.getKey();
					if (!fFound.contains(key)) {
						fFound.add(key);
						fBindings.add(variable);
					}
				}
			return false;
		}
	}

	/**
	 * AST visitor to find recursive calls to the method.
	 */
	public final class RecursiveCallFinder extends AstNodeFinder {

		/** The method binding */
		protected final IFunctionBinding fBinding;

		/**
		 * Creates a new recursive call finder.
		 * 
		 * @param declaration
		 *            the method declaration
		 */
		public RecursiveCallFinder(final FunctionDeclaration declaration) {
			Assert.isNotNull(declaration);
			fBinding= declaration.resolveBinding();
		}

		public final boolean visit(final FunctionInvocation node) {
			Assert.isNotNull(node);
			final Expression expression= node.getExpression();
			final IFunctionBinding binding= node.resolveMethodBinding();
			if (binding == null || (!Modifier.isStatic(binding.getModifiers()) && Bindings.equals(binding, fBinding) && (expression == null || expression instanceof ThisExpression))) {
				fStatus.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_potentially_recursive, JavaStatusContext.create(fMethod.getJavaScriptUnit(), node)));
				fResult.add(node);
				return false;
			}
			return true;
		}
	}

	/**
	 * AST visitor to find 'super' references.
	 */
	public final class SuperReferenceFinder extends AstNodeFinder {

		public final boolean visit(final AnonymousClassDeclaration node) {
			return false;
		}

		public final boolean visit(final SuperFieldAccess node) {
			Assert.isNotNull(node);
			fStatus.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_uses_super, JavaStatusContext.create(fMethod.getJavaScriptUnit(), node)));
			fResult.add(node);
			return false;
		}

		public final boolean visit(final SuperMethodInvocation node) {
			Assert.isNotNull(node);
			fStatus.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_uses_super, JavaStatusContext.create(fMethod.getJavaScriptUnit(), node)));
			fResult.add(node);
			return false;
		}

		public final boolean visit(final TypeDeclaration node) {
			return false;
		}
	}

	/**
	 * AST visitor to find references to 'this'.
	 */
	public final class ThisReferenceFinder extends AstNodeFinder {

		public final boolean visit(final FunctionInvocation node) {
			Assert.isNotNull(node);
			final IFunctionBinding binding= node.resolveMethodBinding();
			if (binding != null && !JdtFlags.isStatic(binding) && node.getExpression() == null) {
				fResult.add(node);
				fStatus.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_this_reference, JavaStatusContext.create(fMethod.getJavaScriptUnit(), node)));
			}
			return true;
		}

		public final boolean visit(final SimpleName node) {
			Assert.isNotNull(node);
			if (isFieldAccess(node) && !isTargetAccess(node)) {
				fResult.add(node);
				fStatus.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_this_reference, JavaStatusContext.create(fMethod.getJavaScriptUnit(), node)));
			}
			return false;
		}

		public final boolean visit(final ThisExpression node) {
			Assert.isNotNull(node);
			fResult.add(node);
			fStatus.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_this_reference, JavaStatusContext.create(fMethod.getJavaScriptUnit(), node)));
			return false;
		}
	}

	/**
	 * Argument factory which adjusts the visibilities of the argument types.
	 */
	public class VisibilityAdjustingArgumentFactory implements IArgumentFactory {

		/** The visibility adjustments */
		private final Map fAdjustments;

		/** The ast to use for new nodes */
		private final AST fAst;

		/** The compilation unit rewrites */
		private final Map fRewrites;

		/**
		 * Creates a new visibility adjusting argument factory.
		 * 
		 * @param ast
		 *            the ast to use for new nodes
		 * @param rewrites
		 *            the compilation unit rewrites
		 * @param adjustments
		 *            the map of elements to visibility adjustments
		 */
		public VisibilityAdjustingArgumentFactory(final AST ast, final Map rewrites, final Map adjustments) {
			Assert.isNotNull(ast);
			Assert.isNotNull(rewrites);
			Assert.isNotNull(adjustments);
			fAst= ast;
			fRewrites= rewrites;
			fAdjustments= adjustments;
		}

		protected final void adjustTypeVisibility(final ITypeBinding binding) throws JavaScriptModelException {
			Assert.isNotNull(binding);
			final IJavaScriptElement element= binding.getJavaElement();
			if (element instanceof IType) {
				final IType type= (IType) element;
				if (!type.isBinary() && !type.isReadOnly() && !Flags.isPublic(type.getFlags())) {
					boolean same= false;
					final CompilationUnitRewrite rewrite= getCompilationUnitRewrite(fRewrites, type.getJavaScriptUnit());
					final AbstractTypeDeclaration declaration= ASTNodeSearchUtil.getAbstractTypeDeclarationNode(type, rewrite.getRoot());
					if (declaration != null) {
						final ITypeBinding declaring= declaration.resolveBinding();
						if (declaring != null && Bindings.equals(binding.getPackage(), fTarget.getType().getPackage()))
							same= true;
						final Modifier.ModifierKeyword keyword= same ? null : Modifier.ModifierKeyword.PUBLIC_KEYWORD;
						final String modifier= same ? RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_default : RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_public;
						if (MemberVisibilityAdjustor.hasLowerVisibility(binding.getModifiers(), same ? Modifier.NONE : (keyword == null ? Modifier.NONE : keyword.toFlagValue())) && MemberVisibilityAdjustor.needsVisibilityAdjustments(type, keyword, fAdjustments))
							fAdjustments.put(type, new MemberVisibilityAdjustor.OutgoingMemberVisibilityAdjustment(type, keyword, RefactoringStatus.createWarningStatus(Messages.format(RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_type_warning, new String[] { BindingLabelProvider.getBindingLabel(declaration.resolveBinding(), JavaScriptElementLabels.ALL_FULLY_QUALIFIED), modifier }), JavaStatusContext.create(type.getJavaScriptUnit(), declaration))));
					}
				}
			}
		}

		public ASTNode getArgumentNode(final IVariableBinding binding, final boolean last) throws JavaScriptModelException {
			Assert.isNotNull(binding);
			adjustTypeVisibility(binding.getType());
			return fAst.newSimpleName(binding.getName());
		}

		public ASTNode getTargetNode() throws JavaScriptModelException {
			return fAst.newThisExpression();
		}
	}

	private static final String ATTRIBUTE_DEPRECATE= "deprecate"; //$NON-NLS-1$

	private static final String ATTRIBUTE_INLINE= "inline"; //$NON-NLS-1$

	private static final String ATTRIBUTE_REMOVE= "remove"; //$NON-NLS-1$

	private static final String ATTRIBUTE_TARGET_INDEX= "targetIndex"; //$NON-NLS-1$

	private static final String ATTRIBUTE_TARGET_NAME= "targetName"; //$NON-NLS-1$

	private static final String ATTRIBUTE_USE_GETTER= "getter"; //$NON-NLS-1$

	private static final String ATTRIBUTE_USE_SETTER= "setter"; //$NON-NLS-1$

	/** The identifier of this processor */
	public static final String IDENTIFIER= "org.eclipse.wst.jsdt.ui.moveInstanceMethodProcessor"; //$NON-NLS-1$

	/**
	 * Returns the bindings of the method arguments of the specified
	 * declaration.
	 * 
	 * @param declaration
	 *            the method declaration
	 * @return the array of method argument variable bindings
	 */
	protected static IVariableBinding[] getArgumentBindings(final FunctionDeclaration declaration) {
		Assert.isNotNull(declaration);
		final List parameters= new ArrayList(declaration.parameters().size());
		VariableDeclaration variable= null;
		IVariableBinding binding= null;
		for (final Iterator iterator= declaration.parameters().iterator(); iterator.hasNext();) {
			variable= (VariableDeclaration) iterator.next();
			binding= variable.resolveBinding();
			if (binding == null)
				return new IVariableBinding[0];
			parameters.add(binding);
		}
		final IVariableBinding[] result= new IVariableBinding[parameters.size()];
		parameters.toArray(result);
		return result;
	}

	/**
	 * Returns the bindings of the method argument types of the specified
	 * declaration.
	 * 
	 * @param declaration
	 *            the method declaration
	 * @return the array of method argument variable bindings
	 */
	protected static ITypeBinding[] getArgumentTypes(final FunctionDeclaration declaration) {
		Assert.isNotNull(declaration);
		final IVariableBinding[] parameters= getArgumentBindings(declaration);
		final List types= new ArrayList(parameters.length);
		IVariableBinding binding= null;
		ITypeBinding type= null;
		for (int index= 0; index < parameters.length; index++) {
			binding= parameters[index];
			type= binding.getType();
			if (type != null)
				types.add(type);
		}
		final ITypeBinding[] result= new ITypeBinding[types.size()];
		types.toArray(result);
		return result;
	}

	/**
	 * Is the specified name a field access?
	 * 
	 * @param name
	 *            the name to check
	 * @return <code>true</code> if this name is a field access,
	 *         <code>false</code> otherwise
	 */
	protected static boolean isFieldAccess(final SimpleName name) {
		Assert.isNotNull(name);
		final IBinding binding= name.resolveBinding();
		if (!(binding instanceof IVariableBinding))
			return false;
		final IVariableBinding variable= (IVariableBinding) binding;
		if (!variable.isField())
			return false;
		if ("length".equals(name.getIdentifier())) { //$NON-NLS-1$
			final ASTNode parent= name.getParent();
			if (parent instanceof QualifiedName) {
				final QualifiedName qualified= (QualifiedName) parent;
				final ITypeBinding type= qualified.getQualifier().resolveTypeBinding();
				if (type != null && type.isArray())
					return false;
			}
		}
		return !Modifier.isStatic(variable.getModifiers());
	}

	/** The candidate targets */
	private IVariableBinding[] fCandidateTargets= new IVariableBinding[0];

	/** The text change manager */
	private TextChangeManager fChangeManager= null;

	/** The comment */
	private String fComment;

	/** Should the delegator be deprecated? */
	private boolean fDelegateDeprecation= true;

	private boolean fDelegatingUpdating;

	/** Should the delegator be inlined? */
	private boolean fInline= false;

	/** The method to move */
	private IFunction fMethod;

	/** The name of the new method to generate */
	private String fMethodName;

	/** The possible targets */
	private IVariableBinding[] fPossibleTargets= new IVariableBinding[0];

	/** Should the delegator be removed after inlining? */
	private boolean fRemove= false;

	/** The code generation settings to apply */
	private CodeGenerationSettings fSettings;

	/** The source compilation unit rewrite */
	private CompilationUnitRewrite fSourceRewrite;

	/** The new target */
	private IVariableBinding fTarget= null;

	/** The name of the new target */
	private String fTargetName;

	/** Does the move method need a target node? */
	private boolean fTargetNode= true;

	/** The target type */
	private IType fTargetType= null;

	/** Should getter methods be used to resolve visibility issues? */
	private boolean fUseGetters= true;

	/** Should setter methods be used to resolve visibility issues? */
	private boolean fUseSetters= true;

	/**
	 * Creates a new move instance method processor.
	 * 
	 * @param method
	 *            the method to move, or <code>null</code> if invoked by
	 *            scripting
	 * @param settings
	 *            the code generation settings to apply, or <code>null</code>
	 *            if invoked by scripting
	 */
	public MoveInstanceMethodProcessor(final IFunction method, final CodeGenerationSettings settings) {
		fSettings= settings;
		fMethod= method;
		if (method != null)
			initialize(method);
	}

	/**
	 * {@inheritDoc}
	 */
	public boolean canEnableComment() {
		return true;
	}

	/**
	 * {@inheritDoc}
	 */
	public final boolean canEnableDelegateUpdating() {
		return true;
	}

	/**
	 * Checks whether a method with the proposed name already exists in the
	 * target type.
	 * 
	 * @param monitor
	 *            the progress monitor to display progress
	 * @param status
	 *            the status of the condition checking
	 * @throws JavaScriptModelException
	 *             if the declared methods of the target type could not be
	 *             retrieved
	 */
	protected void checkConflictingMethod(final IProgressMonitor monitor, final RefactoringStatus status) throws JavaScriptModelException {
		Assert.isNotNull(monitor);
		Assert.isNotNull(status);
		final IFunction[] methods= fTargetType.getFunctions();
		try {
			monitor.beginTask("", methods.length); //$NON-NLS-1$
			monitor.setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_checking);
			IFunction method= null;
			for (int index= 0; index < methods.length; index++) {
				method= methods[index];
				if (method.getElementName().equals(fMethodName) && method.getParameterTypes().length == fMethod.getParameterTypes().length - 1)
					status.merge(RefactoringStatus.createErrorStatus(Messages.format(RefactoringCoreMessages.MoveInstanceMethodProcessor_method_already_exists, new String[] { fMethodName, fTargetType.getElementName() }), JavaStatusContext.create(method)));
				monitor.worked(1);
			}
			if (fMethodName.equals(fTargetType.getElementName()))
				status.merge(RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.MoveInstanceMethodProcessor_method_type_clash, fMethodName), JavaStatusContext.create(fTargetType)));
		} finally {
			monitor.done();
		}
	}

	/**
	 * Checks whether the new target name conflicts with an already existing
	 * method parameter.
	 * 
	 * @param monitor
	 *            the progress monitor to display progress
	 * @param status
	 *            the status of the condition checking
	 * @throws JavaScriptModelException
	 *             if the method declaration of the method to move could not be
	 *             found
	 */
	protected void checkConflictingTarget(final IProgressMonitor monitor, final RefactoringStatus status) throws JavaScriptModelException {
		Assert.isNotNull(monitor);
		Assert.isNotNull(status);
		final FunctionDeclaration declaration= ASTNodeSearchUtil.getMethodDeclarationNode(fMethod, fSourceRewrite.getRoot());
		VariableDeclaration variable= null;
		final List parameters= declaration.parameters();
		try {
			monitor.beginTask("", parameters.size()); //$NON-NLS-1$
			monitor.setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_checking);
			for (final Iterator iterator= parameters.iterator(); iterator.hasNext();) {
				variable= (VariableDeclaration) iterator.next();
				if (fTargetName.equals(variable.getName().getIdentifier())) {
					status.merge(RefactoringStatus.createErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_target_name_already_used, JavaStatusContext.create(fMethod)));
					break;
				}
				monitor.worked(1);
			}
		} finally {
			monitor.done();
		}
	}

	/*
	 * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor#checkFinalConditions(org.eclipse.core.runtime.IProgressMonitor,
	 *      org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext)
	 */
	public final RefactoringStatus checkFinalConditions(final IProgressMonitor monitor, final CheckConditionsContext context) throws CoreException, OperationCanceledException {
		Assert.isNotNull(monitor);
		Assert.isNotNull(context);
		Assert.isNotNull(fTarget);
		final RefactoringStatus status= new RefactoringStatus();
		fChangeManager= new TextChangeManager();
		try {
			monitor.beginTask("", 4); //$NON-NLS-1$
			monitor.setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_checking);
			status.merge(Checks.checkIfCuBroken(fMethod));
			if (!status.hasError()) {
				checkGenericTarget(new SubProgressMonitor(monitor, 1), status);
				if (status.isOK()) {
					final IType type= getTargetType();
					if (type != null) {
						if (type.isBinary() || type.isReadOnly() || !fMethod.exists() || fMethod.isBinary() || fMethod.isReadOnly())
							status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_no_binary, JavaStatusContext.create(fMethod)));
						else {
							status.merge(Checks.checkIfCuBroken(type));
							if (!status.hasError()) {
								if (!type.exists() || type.isBinary() || type.isReadOnly())
									status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_no_binary, JavaStatusContext.create(fMethod)));
								checkConflictingTarget(new SubProgressMonitor(monitor, 1), status);
								checkConflictingMethod(new SubProgressMonitor(monitor, 1), status);
								status.merge(Checks.validateModifiesFiles(computeModifiedFiles(fMethod.getJavaScriptUnit(), type.getJavaScriptUnit()), null));
								monitor.worked(1);
								if (!status.hasFatalError())
									fChangeManager= createChangeManager(status, new SubProgressMonitor(monitor, 1));
							}
						}
					} else
						status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_no_resolved_target, JavaStatusContext.create(fMethod)));
				}
			}
		} finally {
			monitor.done();
		}
		return status;
	}

	/**
	 * Checks whether the target is a type variable or a generic type.
	 * 
	 * @param monitor
	 *            the progress monitor to display progress
	 * @param status
	 *            the refactoring status
	 */
	protected void checkGenericTarget(final IProgressMonitor monitor, final RefactoringStatus status) {
		Assert.isNotNull(monitor);
		Assert.isNotNull(status);
		try {
			monitor.beginTask("", 1); //$NON-NLS-1$
			monitor.setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_checking);
			final ITypeBinding binding= fTarget.getType();
			if (binding == null || binding.isTypeVariable())
				status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_no_generic_targets, JavaStatusContext.create(fMethod)));
		} finally {
			monitor.done();
		}
	}

	/**
	 * Checks whether the method has references to type variables or generic
	 * types.
	 * 
	 * @param monitor
	 *            the progress monitor to display progress
	 * @param declaration
	 *            the method declaration to check for generic types
	 * @param status
	 *            the status of the condition checking
	 */
	protected void checkGenericTypes(final IProgressMonitor monitor, final FunctionDeclaration declaration, final RefactoringStatus status) {
		Assert.isNotNull(monitor);
		Assert.isNotNull(declaration);
		Assert.isNotNull(status);
		try {
			monitor.beginTask("", 1); //$NON-NLS-1$
			monitor.setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_checking);
			final AstNodeFinder finder= new GenericReferenceFinder(declaration);
			declaration.accept(finder);
			if (!finder.getStatus().isOK())
				status.merge(finder.getStatus());
		} finally {
			monitor.done();
		}
	}

	/*
	 * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor#checkInitialConditions(org.eclipse.core.runtime.IProgressMonitor)
	 */
	public final RefactoringStatus checkInitialConditions(final IProgressMonitor monitor) throws CoreException, OperationCanceledException {
		Assert.isNotNull(monitor);
		final RefactoringStatus status= new RefactoringStatus();
		try {
			monitor.beginTask("", 4); //$NON-NLS-1$
			monitor.setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_checking);
			status.merge(Checks.checkIfCuBroken(fMethod));
			if (!status.hasError()) {
				checkMethodDeclaration(new SubProgressMonitor(monitor, 1), status);
				if (status.isOK()) {
					final FunctionDeclaration declaration= ASTNodeSearchUtil.getMethodDeclarationNode(fMethod, fSourceRewrite.getRoot());
					checkGenericTypes(new SubProgressMonitor(monitor, 1), declaration, status);
					checkMethodBody(new SubProgressMonitor(monitor, 1), declaration, status);
					checkPossibleTargets(new SubProgressMonitor(monitor, 1), declaration, status);
				}
			}
		} finally {
			monitor.done();
		}
		return status;
	}

	/**
	 * Checks whether the instance method body is compatible with this
	 * refactoring.
	 * 
	 * @param monitor
	 *            the progress monitor to display progress
	 * @param declaration
	 *            the method declaration whose body to check
	 * @param status
	 *            the status of the condition checking
	 */
	protected void checkMethodBody(final IProgressMonitor monitor, final FunctionDeclaration declaration, final RefactoringStatus status) {
		Assert.isNotNull(monitor);
		Assert.isNotNull(declaration);
		Assert.isNotNull(status);
		try {
			monitor.beginTask("", 3); //$NON-NLS-1$
			monitor.setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_checking);
			AstNodeFinder finder= new SuperReferenceFinder();
			declaration.accept(finder);
			if (!finder.getStatus().isOK())
				status.merge(finder.getStatus());
			monitor.worked(1);
			finder= null;
			final IFunctionBinding binding= declaration.resolveBinding();
			if (binding != null) {
				final ITypeBinding declaring= binding.getDeclaringClass();
				if (declaring != null)
					finder= new EnclosingInstanceReferenceFinder(declaring);
			}
			if (finder != null) {
				declaration.accept(finder);
				if (!finder.getStatus().isOK())
					status.merge(finder.getStatus());
				monitor.worked(1);
				finder= new RecursiveCallFinder(declaration);
				declaration.accept(finder);
				if (!finder.getStatus().isOK())
					status.merge(finder.getStatus());
				monitor.worked(1);
			}
		} finally {
			monitor.done();
		}
	}

	/**
	 * Checks whether the instance method declaration is compatible with this
	 * refactoring.
	 * 
	 * @param monitor
	 *            the progress monitor to display progress
	 * @param status
	 *            the status of the condition checking
	 * @throws JavaScriptModelException
	 *             if the method does not exist
	 */
	protected void checkMethodDeclaration(final IProgressMonitor monitor, final RefactoringStatus status) throws JavaScriptModelException {
		Assert.isNotNull(monitor);
		Assert.isNotNull(status);
		try {
			monitor.beginTask("", 5); //$NON-NLS-1$
			monitor.setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_checking);
			final int flags= fMethod.getFlags();
			if (Flags.isStatic(flags))
				status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_no_static_methods, JavaStatusContext.create(fMethod)));
			else if (Flags.isAbstract(flags))
				status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_single_implementation, JavaStatusContext.create(fMethod)));
			monitor.worked(1);
			if (Flags.isNative(flags))
				status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_no_native_methods, JavaStatusContext.create(fMethod)));
			monitor.worked(1);
			if (Flags.isSynchronized(flags))
				status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_no_synchronized_methods, JavaStatusContext.create(fMethod)));
			monitor.worked(1);
			if (fMethod.isConstructor())
				status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_no_constructors, JavaStatusContext.create(fMethod)));
			monitor.worked(1);
//			if (fMethod.getDeclaringType().isAnnotation())
//				status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_no_annotation, JavaStatusContext.create(fMethod)));
//			else if (fMethod.getDeclaringType().isInterface())
//				status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_no_interface, JavaStatusContext.create(fMethod)));
			monitor.worked(1);
		} finally {
			monitor.done();
		}
	}

	/**
	 * Checks whether the method has possible targets to be moved to
	 * 
	 * @param monitor
	 *            the progress monitor to display progress
	 * @param declaration
	 *            the method declaration to check
	 * @param status
	 *            the status of the condition checking
	 */
	protected void checkPossibleTargets(final IProgressMonitor monitor, final FunctionDeclaration declaration, final RefactoringStatus status) {
		Assert.isNotNull(monitor);
		Assert.isNotNull(declaration);
		Assert.isNotNull(status);
		try {
			monitor.beginTask("", 1); //$NON-NLS-1$
			monitor.setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_checking);
			if (computeTargetCategories(declaration).length < 1)
				status.merge(RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.MoveInstanceMethodProcessor_cannot_be_moved, JavaStatusContext.create(fMethod)));
		} finally {
			monitor.done();
		}
	}

	/**
	 * Searches for references to the original method.
	 * 
	 * @param monitor
	 *            the progress monitor to use
	 * @param status
	 *            the refactoring status to use
	 * @return the array of search result groups
	 * @throws CoreException
	 *             if an error occurred during search
	 */
	protected SearchResultGroup[] computeMethodReferences(final IProgressMonitor monitor, final RefactoringStatus status) throws CoreException {
		Assert.isNotNull(monitor);
		Assert.isNotNull(status);
		try {
			monitor.beginTask("", 1); //$NON-NLS-1$
			monitor.setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_checking);
			final RefactoringSearchEngine2 engine= new RefactoringSearchEngine2(SearchPattern.createPattern(fMethod, IJavaScriptSearchConstants.REFERENCES, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE));
			engine.setStatus(status);
			engine.searchPattern(new SubProgressMonitor(monitor, 1));
			return (SearchResultGroup[]) engine.getResults();
		} finally {
			monitor.done();
		}
	}

	/**
	 * Computes the files that are being modified by this refactoring.
	 * 
	 * @param source
	 *            the source compilation unit
	 * @param target
	 *            the target compilation unit
	 * @return the modified files
	 */
	protected IFile[] computeModifiedFiles(final IJavaScriptUnit source, final IJavaScriptUnit target) {
		Assert.isNotNull(source);
		Assert.isNotNull(target);
		if (source.equals(target))
			return ResourceUtil.getFiles(new IJavaScriptUnit[] { source });
		return ResourceUtil.getFiles(new IJavaScriptUnit[] { source, target });
	}

	/**
	 * Returns the reserved identifiers in the method to move.
	 * 
	 * @return the reserved identifiers
	 * @throws JavaScriptModelException
	 *             if the method declaration could not be found
	 */
	protected String[] computeReservedIdentifiers() throws JavaScriptModelException {
		final List names= new ArrayList();
		final FunctionDeclaration declaration= ASTNodeSearchUtil.getMethodDeclarationNode(fMethod, fSourceRewrite.getRoot());
		if (declaration != null) {
			final List parameters= declaration.parameters();
			VariableDeclaration variable= null;
			for (int index= 0; index < parameters.size(); index++) {
				variable= (VariableDeclaration) parameters.get(index);
				names.add(variable.getName().getIdentifier());
			}
			final Block body= declaration.getBody();
			if (body != null) {
				final IBinding[] bindings= new ScopeAnalyzer(fSourceRewrite.getRoot()).getDeclarationsAfter(body.getStartPosition(), ScopeAnalyzer.VARIABLES);
				for (int index= 0; index < bindings.length; index++)
					names.add(bindings[index].getName());
			}
		}
		final String[] result= new String[names.size()];
		names.toArray(result);
		return result;
	}

	/**
	 * Computes the target categories for the method to move.
	 * 
	 * @param declaration
	 *            the method declaration
	 * @return the possible targets as variable bindings of read-only fields and
	 *         parameters
	 */
	protected IVariableBinding[] computeTargetCategories(final FunctionDeclaration declaration) {
		Assert.isNotNull(declaration);
		if (fPossibleTargets.length == 0 || fCandidateTargets.length == 0) {
			final List possibleTargets= new ArrayList(16);
			final List candidateTargets= new ArrayList(16);
			final IFunctionBinding method= declaration.resolveBinding();
			if (method != null) {
				final ITypeBinding declaring= method.getDeclaringClass();
				IVariableBinding[] bindings= getArgumentBindings(declaration);
				ITypeBinding binding= null;
				for (int index= 0; index < bindings.length; index++) {
					binding= bindings[index].getType();
					if ((binding.isClass() || binding.isEnum()) && binding.isFromSource()) {
						possibleTargets.add(bindings[index]);
						candidateTargets.add(bindings[index]);
					}
				}
				final ReadyOnlyFieldFinder visitor= new ReadyOnlyFieldFinder(declaring);
				declaration.accept(visitor);
				bindings= visitor.getReadOnlyFields();
				for (int index= 0; index < bindings.length; index++) {
					binding= bindings[index].getType();
					if (binding.isClass() && binding.isFromSource())
						possibleTargets.add(bindings[index]);
				}
				bindings= visitor.getDeclaredFields();
				for (int index= 0; index < bindings.length; index++) {
					binding= bindings[index].getType();
					if (binding.isClass() && binding.isFromSource())
						candidateTargets.add(bindings[index]);
				}
			}
			fPossibleTargets= new IVariableBinding[possibleTargets.size()];
			possibleTargets.toArray(fPossibleTargets);
			fCandidateTargets= new IVariableBinding[candidateTargets.size()];
			candidateTargets.toArray(fCandidateTargets);
		}
		return fPossibleTargets;
	}

	/**
	 * Creates a visibility-adjusted target expression taking advantage of
	 * existing accessor methods.
	 * 
	 * @param enclosingElement
	 *            the java element which encloses the current method access.
	 * @param expression
	 *            the expression to access the target, or <code>null</code>
	 * @param adjustments
	 *            the map of elements to visibility adjustments
	 * @param rewrite
	 *            the ast rewrite to use
	 * @return an adjusted target expression, or <code>null</code> if the
	 *         access did not have to be changed
	 * @throws JavaScriptModelException
	 *             if an error occurs while accessing the target expression
	 */
	protected Expression createAdjustedTargetExpression(final IJavaScriptElement enclosingElement, final Expression expression, final Map adjustments, final ASTRewrite rewrite) throws JavaScriptModelException {
		Assert.isNotNull(enclosingElement);
		Assert.isNotNull(adjustments);
		Assert.isNotNull(rewrite);
		final IJavaScriptElement element= fTarget.getJavaElement();
		if (element != null && !Modifier.isPublic(fTarget.getModifiers())) {
			final IField field= (IField) fTarget.getJavaElement();
			if (field != null) {
				boolean same= field.getAncestor(IJavaScriptElement.PACKAGE_FRAGMENT).equals(enclosingElement.getAncestor(IJavaScriptElement.PACKAGE_FRAGMENT));
				final Modifier.ModifierKeyword keyword= same ? null : Modifier.ModifierKeyword.PUBLIC_KEYWORD;
				final String modifier= same ? RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_default : RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_public;
				if (fUseGetters) {
					final IFunction getter= GetterSetterUtil.getGetter(field);
					if (getter != null) {
						final FunctionDeclaration method= ASTNodeSearchUtil.getMethodDeclarationNode(getter, fSourceRewrite.getRoot());
						if (method != null) {
							final IFunctionBinding binding= method.resolveBinding();
							if (binding != null && MemberVisibilityAdjustor.hasLowerVisibility(getter.getFlags(), same ? Modifier.NONE : (keyword == null ? Modifier.NONE : keyword.toFlagValue())) && MemberVisibilityAdjustor.needsVisibilityAdjustments(getter, keyword, adjustments))
								adjustments.put(getter, new MemberVisibilityAdjustor.OutgoingMemberVisibilityAdjustment(getter, keyword, RefactoringStatus.createWarningStatus(Messages.format(RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_method_warning, new String[] { BindingLabelProvider.getBindingLabel(binding, JavaScriptElementLabels.ALL_FULLY_QUALIFIED), modifier }), JavaStatusContext.create(getter))));
							final FunctionInvocation invocation= rewrite.getAST().newFunctionInvocation();
							invocation.setExpression(expression);
							invocation.setName(rewrite.getAST().newSimpleName(getter.getElementName()));
							return invocation;
						}
					}
				}
				if (MemberVisibilityAdjustor.hasLowerVisibility(field.getFlags(), (keyword == null ? Modifier.NONE : keyword.toFlagValue())) && MemberVisibilityAdjustor.needsVisibilityAdjustments(field, keyword, adjustments))
					adjustments.put(field, new MemberVisibilityAdjustor.OutgoingMemberVisibilityAdjustment(field, keyword, RefactoringStatus.createWarningStatus(Messages.format(RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_field_warning, new String[] { BindingLabelProvider.getBindingLabel(fTarget, JavaScriptElementLabels.ALL_FULLY_QUALIFIED), modifier }), JavaStatusContext.create(field))));
			}
		}
		return null;
	}

	/**
	 * Creates a generic argument list of the refactored moved method
	 * 
	 * @param declaration
	 *            the method declaration of the method to move
	 * @param arguments
	 *            the argument list to create
	 * @param factory
	 *            the argument factory to use
	 * @return <code>true</code> if a target node had to be inserted as first
	 *         argument, <code>false</code> otherwise
	 * @throws JavaScriptModelException
	 *             if an error occurs
	 */
	protected boolean createArgumentList(final FunctionDeclaration declaration, final List arguments, final IArgumentFactory factory) throws JavaScriptModelException {
		Assert.isNotNull(declaration);
		Assert.isNotNull(arguments);
		Assert.isNotNull(factory);
		final AstNodeFinder finder= new ThisReferenceFinder();
		declaration.accept(finder);
		IVariableBinding binding= null;
		VariableDeclaration variable= null;
		boolean added= false;
		final int size= declaration.parameters().size();
		for (int index= 0; index < size; index++) {
			variable= (VariableDeclaration) declaration.parameters().get(index);
			binding= variable.resolveBinding();
			if (binding != null) {
				if (!Bindings.equals(binding, fTarget))
					arguments.add(factory.getArgumentNode(binding, index == size - 1));
				else if (!finder.getStatus().isOK()) {
					arguments.add(factory.getTargetNode());
					added= true;
				}
			} else
				arguments.add(factory.getArgumentNode(binding, index == size - 1));
		}
		if (!finder.getStatus().isOK() && !added) {
			arguments.add(0, factory.getTargetNode());
			added= true;
		}
		return added;
	}

	/*
	 * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor#createChange(org.eclipse.core.runtime.IProgressMonitor)
	 */
	public final Change createChange(final IProgressMonitor monitor) throws CoreException, OperationCanceledException {
		Assert.isNotNull(monitor);
		try {
			monitor.beginTask("", 6); //$NON-NLS-1$
			monitor.setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_creating);
			final TextChange[] changes= fChangeManager.getAllChanges();
			if (changes.length == 1)
				return changes[0];
			final List list= new ArrayList(changes.length);
			list.addAll(Arrays.asList(changes));
			final Map arguments= new HashMap();
			String project= null;
			final IJavaScriptProject javaProject= fMethod.getJavaScriptProject();
			if (javaProject != null)
				project= javaProject.getElementName();
			int flags= JavaScriptRefactoringDescriptor.JAR_REFACTORING | JavaScriptRefactoringDescriptor.JAR_SOURCE_ATTACHMENT | RefactoringDescriptor.STRUCTURAL_CHANGE | RefactoringDescriptor.MULTI_CHANGE;
			final IType declaring= fMethod.getDeclaringType();
			try {
				if (declaring.isAnonymous() || declaring.isLocal())
					flags|= JavaScriptRefactoringDescriptor.JAR_SOURCE_ATTACHMENT;
			} catch (JavaScriptModelException exception) {
				JavaScriptPlugin.log(exception);
			}
			final String description= Messages.format(RefactoringCoreMessages.MoveInstanceMethodProcessor_descriptor_description_short, fMethod.getElementName());
			final String header= Messages.format(RefactoringCoreMessages.MoveInstanceMethodProcessor_descriptor_description, new String[] { JavaScriptElementLabels.getElementLabel(fMethod, JavaScriptElementLabels.ALL_FULLY_QUALIFIED), BindingLabelProvider.getBindingLabel(fTarget, JavaScriptElementLabels.ALL_FULLY_QUALIFIED) });
			final JDTRefactoringDescriptorComment comment= new JDTRefactoringDescriptorComment(project, this, header);
			comment.addSetting(Messages.format(RefactoringCoreMessages.MoveInstanceMethodProcessor_moved_element_pattern, RefactoringCoreMessages.JavaRefactoringDescriptor_not_available));
			comment.addSetting(Messages.format(RefactoringCoreMessages.MoveInstanceMethodProcessor_target_element_pattern, BindingLabelProvider.getBindingLabel(fTarget, JavaScriptElementLabels.ALL_FULLY_QUALIFIED)));
			comment.addSetting(Messages.format(RefactoringCoreMessages.MoveInstanceMethodProcessor_method_name_pattern, getMethodName()));
			if (needsTargetNode())
				comment.addSetting(Messages.format(RefactoringCoreMessages.MoveInstanceMethodProcessor_parameter_name_pattern, getTargetName()));
			final JDTRefactoringDescriptor descriptor= new JDTRefactoringDescriptor(IJavaScriptRefactorings.MOVE_METHOD, project, description, comment.asString(), arguments, flags);
			arguments.put(JDTRefactoringDescriptor.ATTRIBUTE_INPUT, descriptor.elementToHandle(fMethod));
			arguments.put(JDTRefactoringDescriptor.ATTRIBUTE_NAME, fMethodName);
			arguments.put(ATTRIBUTE_TARGET_NAME, fTargetName);
			arguments.put(ATTRIBUTE_DEPRECATE, Boolean.valueOf(fDelegateDeprecation).toString());
			arguments.put(ATTRIBUTE_REMOVE, Boolean.valueOf(fRemove).toString());
			arguments.put(ATTRIBUTE_INLINE, Boolean.valueOf(fInline).toString());
			arguments.put(ATTRIBUTE_USE_GETTER, Boolean.valueOf(fUseGetters).toString());
			arguments.put(ATTRIBUTE_USE_SETTER, Boolean.valueOf(fUseSetters).toString());
			arguments.put(ATTRIBUTE_TARGET_INDEX, new Integer(getTargetIndex()).toString());
			return new DynamicValidationRefactoringChange(descriptor, RefactoringCoreMessages.MoveInstanceMethodRefactoring_name, (Change[]) list.toArray(new Change[list.size()]));
		} finally {
			monitor.done();
		}
	}

	/**
	 * Creates the text change manager for this processor.
	 * 
	 * @param status
	 *            the refactoring status
	 * @param monitor
	 *            the progress monitor to display progress
	 * @return the created text change manager
	 * @throws JavaScriptModelException
	 *             if the method declaration could not be found
	 * @throws CoreException
	 *             if the changes could not be generated
	 */
	protected TextChangeManager createChangeManager(final RefactoringStatus status, final IProgressMonitor monitor) throws JavaScriptModelException, CoreException {
		Assert.isNotNull(status);
		Assert.isNotNull(monitor);
		try {
			monitor.beginTask("", 7); //$NON-NLS-1$
			monitor.setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_creating);
			fSourceRewrite.clearASTAndImportRewrites();
			final TextChangeManager manager= new TextChangeManager();
			final CompilationUnitRewrite targetRewrite= fMethod.getJavaScriptUnit().equals(getTargetType().getJavaScriptUnit()) ? fSourceRewrite : new CompilationUnitRewrite(getTargetType().getJavaScriptUnit());
			final FunctionDeclaration declaration= ASTNodeSearchUtil.getMethodDeclarationNode(fMethod, fSourceRewrite.getRoot());
			final SearchResultGroup[] references= computeMethodReferences(new SubProgressMonitor(monitor, 1), status);
			final Map rewrites= new HashMap(2);
			rewrites.put(fSourceRewrite.getCu(), fSourceRewrite);
			if (!fSourceRewrite.getCu().equals(targetRewrite.getCu()))
				rewrites.put(targetRewrite.getCu(), targetRewrite);
			final ASTRewrite sourceRewrite= ASTRewrite.create(fSourceRewrite.getRoot().getAST());
			final MemberVisibilityAdjustor adjustor= new MemberVisibilityAdjustor(fTargetType, fMethod);
			adjustor.setStatus(status);
			adjustor.setVisibilitySeverity(RefactoringStatus.WARNING);
			adjustor.setFailureSeverity(RefactoringStatus.WARNING);
			adjustor.setRewrites(rewrites);
			adjustor.setRewrite(sourceRewrite, fSourceRewrite.getRoot());
			adjustor.adjustVisibility(new SubProgressMonitor(monitor, 1));
			final IDocument document= new Document(fMethod.getJavaScriptUnit().getBuffer().getContents());
			final boolean target= createMethodCopy(document, declaration, sourceRewrite, rewrites, adjustor.getAdjustments(), status, new SubProgressMonitor(monitor, 1));
			createMethodJavadocReferences(rewrites, declaration, references, target, status, new SubProgressMonitor(monitor, 1));
			if (!fSourceRewrite.getCu().equals(targetRewrite.getCu()))
				createMethodImports(targetRewrite, declaration, new SubProgressMonitor(monitor, 1), status);
			boolean removable= false;
			if (fInline) {
				removable= createMethodDelegator(rewrites, declaration, references, adjustor.getAdjustments(), target, status, new SubProgressMonitor(monitor, 1));
				if (fRemove && removable) {
					fSourceRewrite.getASTRewrite().remove(declaration, fSourceRewrite.createGroupDescription(RefactoringCoreMessages.MoveInstanceMethodProcessor_remove_original_method));
					if (!fSourceRewrite.getCu().equals(fTargetType.getJavaScriptUnit()))
						fSourceRewrite.getImportRemover().registerRemovedNode(declaration);
				}
			}
			if (!fRemove || !removable)
				createMethodDelegation(declaration, rewrites, adjustor.getAdjustments(), status, new SubProgressMonitor(monitor, 1));

			// Do not adjust visibility of a target field; references to the
			// field will be removed anyway.
			final IJavaScriptElement targetElement= fTarget.getJavaElement();
			if (targetElement != null && targetElement instanceof IField && (Flags.isPrivate(fMethod.getFlags()) || !fInline)) {
				final IVisibilityAdjustment adjustmentForTarget= (IVisibilityAdjustment) adjustor.getAdjustments().get(targetElement);
				if (adjustmentForTarget != null)
					adjustor.getAdjustments().remove(targetElement);
			}

			adjustor.rewriteVisibility(new SubProgressMonitor(monitor, 1));
			sourceRewrite.rewriteAST(document, fMethod.getJavaScriptProject().getOptions(true));
			createMethodSignature(document, declaration, sourceRewrite, rewrites);
			IJavaScriptUnit unit= null;
			CompilationUnitRewrite rewrite= null;
			for (final Iterator iterator= rewrites.keySet().iterator(); iterator.hasNext();) {
				unit= (IJavaScriptUnit) iterator.next();
				rewrite= (CompilationUnitRewrite) rewrites.get(unit);
				manager.manage(unit, rewrite.createChange());
			}
			return manager;
		} finally {
			monitor.done();
		}
	}

	/**
	 * Creates the necessary change to inline a method invocation represented by
	 * a search match.
	 * 
	 * @param rewriter
	 *            the current compilation unit rewrite
	 * @param declaration
	 *            the source method declaration
	 * @param match
	 *            the search match representing the method invocation
	 * @param adjustments
	 *            the map of elements to visibility adjustments
	 * @param target
	 *            <code>true</code> if a target node had to be inserted as
	 *            first argument, <code>false</code> otherwise
	 * @param status
	 *            the refactoring status
	 * @return <code>true</code> if the inline change could be performed,
	 *         <code>false</code> otherwise
	 * @throws JavaScriptModelException
	 *             if a problem occurred while creating the inlined target
	 *             expression for field targets
	 */
	protected boolean createInlinedMethodInvocation(final CompilationUnitRewrite rewriter, final FunctionDeclaration declaration, final SearchMatch match, final Map adjustments, final boolean target, final RefactoringStatus status) throws JavaScriptModelException {
		Assert.isNotNull(rewriter);
		Assert.isNotNull(declaration);
		Assert.isNotNull(match);
		Assert.isNotNull(adjustments);
		Assert.isNotNull(status);
		boolean result= true;
		final ASTRewrite rewrite= rewriter.getASTRewrite();
		final ASTNode node= ASTNodeSearchUtil.findNode(match, rewriter.getRoot());
		final TextEditGroup group= rewriter.createGroupDescription(RefactoringCoreMessages.MoveInstanceMethodProcessor_inline_method_invocation);
		if (node instanceof FunctionInvocation) {
			final FunctionInvocation invocation= (FunctionInvocation) node;
			final ListRewrite list= rewrite.getListRewrite(invocation, FunctionInvocation.ARGUMENTS_PROPERTY);
			if (fTarget.isField()) {
				Expression access= null;
				if (invocation.getExpression() != null) {
					access= createInlinedTargetExpression(rewriter, (IJavaScriptElement) match.getElement(), invocation.getExpression(), adjustments, status);
					rewrite.set(invocation, FunctionInvocation.EXPRESSION_PROPERTY, access, group);
				} else
					rewrite.set(invocation, FunctionInvocation.EXPRESSION_PROPERTY, rewrite.getAST().newSimpleName(fTarget.getName()), group);
				if (target) {
					if (access == null || !(access instanceof FieldAccess))
						list.insertFirst(rewrite.getAST().newThisExpression(), null);
					else
						list.insertLast(rewrite.createCopyTarget(invocation.getExpression()), null);
				}
			} else {
				final IVariableBinding[] bindings= getArgumentBindings(declaration);
				if (bindings.length > 0) {
					int index= 0;
					for (; index < bindings.length; index++)
						if (Bindings.equals(bindings[index], fTarget))
							break;
					if (index < bindings.length && invocation.arguments().size() > index) {
						final Expression argument= (Expression) invocation.arguments().get(index);
						if (argument instanceof NullLiteral) {
							status.merge(RefactoringStatus.createErrorStatus(Messages.format(RefactoringCoreMessages.MoveInstanceMethodProcessor_no_null_argument, BindingLabelProvider.getBindingLabel(declaration.resolveBinding(), JavaScriptElementLabels.ALL_FULLY_QUALIFIED)), JavaStatusContext.create(rewriter.getCu(), invocation)));
							result= false;
						} else {
							if (argument instanceof ThisExpression)
								rewrite.remove(invocation.getExpression(), null);
							else
								rewrite.set(invocation, FunctionInvocation.EXPRESSION_PROPERTY, rewrite.createCopyTarget(argument), group);
							if (target) {
								if (invocation.getExpression() != null)
									list.replace(argument, rewrite.createCopyTarget(invocation.getExpression()), group);
								else {
									final ThisExpression expression= rewrite.getAST().newThisExpression();
									final AbstractTypeDeclaration member= (AbstractTypeDeclaration) ASTNodes.getParent(invocation, AbstractTypeDeclaration.class);
									if (member != null) {
										final ITypeBinding resolved= member.resolveBinding();
										if (ASTNodes.getParent(invocation, AnonymousClassDeclaration.class) != null || (resolved != null && resolved.isMember())) {
											final IFunctionBinding method= declaration.resolveBinding();
											if (method != null) {
												final ITypeBinding declaring= method.getDeclaringClass();
												if (declaring != null)
													expression.setQualifier(rewrite.getAST().newSimpleName(declaring.getName()));
											}
										}
									}
									list.replace(argument, expression, group);
								}
							} else
								list.remove(argument, group);
						}
					}
				}
			}
			if (result)
				rewrite.set(invocation, FunctionInvocation.NAME_PROPERTY, rewrite.getAST().newSimpleName(fMethodName), group);
		}
		return result;
	}

	/**
	 * Creates the target field expression for the inline method invocation.
	 * 
	 * @param rewriter
	 *            the current compilation unit rewrite
	 * @param enclosingElement
	 *            the enclosing java element of the method invocation.
	 * @param original
	 *            the original method invocation expression
	 * @param adjustments
	 *            the map of elements to visibility adjustments
	 * @param status
	 *            the refactoring status
	 * @throws JavaScriptModelException
	 *             if a problem occurred while retrieving potential getter
	 *             methods of the target
	 */
	protected Expression createInlinedTargetExpression(final CompilationUnitRewrite rewriter, final IJavaScriptElement enclosingElement, final Expression original, final Map adjustments, final RefactoringStatus status) throws JavaScriptModelException {
		Assert.isNotNull(rewriter);
		Assert.isNotNull(enclosingElement);
		Assert.isNotNull(original);
		Assert.isNotNull(adjustments);
		Assert.isNotNull(status);
		Assert.isTrue(fTarget.isField());
		final Expression expression= (Expression) ASTNode.copySubtree(fSourceRewrite.getASTRewrite().getAST(), original);
		final Expression result= createAdjustedTargetExpression(enclosingElement, expression, adjustments, fSourceRewrite.getASTRewrite());
		if (result == null) {
			final FieldAccess access= fSourceRewrite.getASTRewrite().getAST().newFieldAccess();
			access.setExpression(expression);
			access.setName(fSourceRewrite.getASTRewrite().getAST().newSimpleName(fTarget.getName()));
			return access;
		}
		return result;
	}

	/**
	 * Creates the method arguments for the target method declaration.
	 * 
	 * @param rewrites
	 *            the compilation unit rewrites
	 * @param rewrite
	 *            the source ast rewrite
	 * @param declaration
	 *            the source method declaration
	 * @param adjustments
	 *            the map of elements to visibility adjustments
	 * @param status
	 *            the refactoring status
	 * @return <code>true</code> if a target node had to be inserted as method
	 *         argument, <code>false</code> otherwise
	 * @throws JavaScriptModelException
	 *             if an error occurs while accessing the types of the arguments
	 */
	protected boolean createMethodArguments(final Map rewrites, final ASTRewrite rewrite, final FunctionDeclaration declaration, final Map adjustments, final RefactoringStatus status) throws JavaScriptModelException {
		Assert.isNotNull(rewrites);
		Assert.isNotNull(declaration);
		Assert.isNotNull(rewrite);
		Assert.isNotNull(adjustments);
		Assert.isNotNull(status);
		final CompilationUnitRewrite rewriter= getCompilationUnitRewrite(rewrites, getTargetType().getJavaScriptUnit());
		final AST ast= rewriter.getRoot().getAST();
		final AstNodeFinder finder= new AnonymousClassReferenceFinder(declaration);
		declaration.accept(finder);
		final List arguments= new ArrayList(declaration.parameters().size() + 1);
		final boolean result= createArgumentList(declaration, arguments, new VisibilityAdjustingArgumentFactory(ast, rewrites, adjustments) {

			public final ASTNode getArgumentNode(final IVariableBinding binding, final boolean last) throws JavaScriptModelException {
				Assert.isNotNull(binding);
				final SingleVariableDeclaration variable= ast.newSingleVariableDeclaration();
				final ITypeBinding type= binding.getType();
				adjustTypeVisibility(type);
				variable.setName(ast.newSimpleName(binding.getName()));
				variable.modifiers().addAll(ast.newModifiers(binding.getModifiers()));
				final IFunctionBinding method= binding.getDeclaringMethod();
				if (last && method != null && method.isVarargs()) {
					variable.setVarargs(true);
					String name= null;
					if (type.isArray()) {
						name= type.getElementType().getName();
						if (PrimitiveType.toCode(name) != null)
							variable.setType(ast.newPrimitiveType(PrimitiveType.toCode(name)));
						else
							variable.setType(ast.newSimpleType(ast.newSimpleName(name)));
					} else {
						name= type.getName();
						if (PrimitiveType.toCode(name) != null)
							variable.setType(ast.newPrimitiveType(PrimitiveType.toCode(name)));
						else
							variable.setType(ast.newSimpleType(ast.newSimpleName(name)));
					}
				} else
					variable.setType(rewriter.getImportRewrite().addImport(type, ast));
				return variable;
			}

			public final ASTNode getTargetNode() throws JavaScriptModelException {
				final SingleVariableDeclaration variable= ast.newSingleVariableDeclaration();
				final IFunctionBinding method= declaration.resolveBinding();
				if (method != null) {
					final ITypeBinding declaring= method.getDeclaringClass();
					if (declaring != null) {
						adjustTypeVisibility(declaring);
						variable.setType(rewriter.getImportRewrite().addImport(declaring, ast));
						variable.setName(ast.newSimpleName(fTargetName));
						if (finder.getResult().size() > 0)
							variable.modifiers().add(ast.newModifier(Modifier.ModifierKeyword.FINAL_KEYWORD));
					}
				}
				return variable;
			}
		});
		final ListRewrite list= rewrite.getListRewrite(declaration, FunctionDeclaration.PARAMETERS_PROPERTY);
		ASTNode node= null;
		for (final Iterator iterator= declaration.parameters().iterator(); iterator.hasNext();) {
			node= (ASTNode) iterator.next();
			list.remove(node, null);
		}
		for (final Iterator iterator= arguments.iterator(); iterator.hasNext();) {
			node= (ASTNode) iterator.next();
			list.insertLast(node, null);
		}
		return result;
	}

	/**
	 * Creates the method body for the target method declaration.
	 * 
	 * @param rewriter
	 *            the target compilation unit rewrite
	 * @param rewrite
	 *            the source ast rewrite
	 * @param declaration
	 *            the source method declaration
	 */
	protected void createMethodBody(final CompilationUnitRewrite rewriter, final ASTRewrite rewrite, final FunctionDeclaration declaration) {
		Assert.isNotNull(declaration);
		declaration.getBody().accept(new MethodBodyRewriter(rewriter, rewrite, declaration));
	}

	/**
	 * Creates the method comment for the target method declaration.
	 * 
	 * @param rewrite
	 *            the source ast rewrite
	 * @param declaration
	 *            the source method declaration
	 * @throws JavaScriptModelException
	 *             if the argument references could not be generated
	 */
	protected void createMethodComment(final ASTRewrite rewrite, final FunctionDeclaration declaration) throws JavaScriptModelException {
		Assert.isNotNull(rewrite);
		Assert.isNotNull(declaration);
		final JSdoc comment= declaration.getJavadoc();
		if (comment != null) {
			final List tags= new LinkedList(comment.tags());
			final IVariableBinding[] bindings= getArgumentBindings(declaration);
			final Map elements= new HashMap(bindings.length);
			String name= null;
			List fragments= null;
			TagElement element= null;
			TagElement reference= null;
			IVariableBinding binding= null;
			for (int index= 0; index < bindings.length; index++) {
				binding= bindings[index];
				for (final Iterator iterator= comment.tags().iterator(); iterator.hasNext();) {
					element= (TagElement) iterator.next();
					name= element.getTagName();
					fragments= element.fragments();
					if (name != null) {
						if (name.equals(TagElement.TAG_PARAM) && !fragments.isEmpty() && fragments.get(0) instanceof SimpleName) {
							final SimpleName simple= (SimpleName) fragments.get(0);
							if (binding.getName().equals(simple.getIdentifier())) {
								elements.put(binding.getKey(), element);
								tags.remove(element);
							}
						} else if (reference == null)
							reference= element;
					}
				}
			}
			if (bindings.length == 0 && reference == null) {
				for (final Iterator iterator= comment.tags().iterator(); iterator.hasNext();) {
					element= (TagElement) iterator.next();
					name= element.getTagName();
					fragments= element.fragments();
					if (name != null && !name.equals(TagElement.TAG_PARAM))
						reference= element;
				}
			}
			final List arguments= new ArrayList(bindings.length + 1);
			createArgumentList(declaration, arguments, new IArgumentFactory() {

				public final ASTNode getArgumentNode(final IVariableBinding argument, final boolean last) throws JavaScriptModelException {
					Assert.isNotNull(argument);
					if (elements.containsKey(argument.getKey()))
						return rewrite.createCopyTarget((ASTNode) elements.get(argument.getKey()));
					return JavadocUtil.createParamTag(argument.getName(), declaration.getAST(), fMethod.getJavaScriptProject());
				}

				public final ASTNode getTargetNode() throws JavaScriptModelException {
					return JavadocUtil.createParamTag(fTargetName, declaration.getAST(), fMethod.getJavaScriptProject());
				}
			});
			final ListRewrite rewriter= rewrite.getListRewrite(comment, JSdoc.TAGS_PROPERTY);
			ASTNode tag= null;
			for (final Iterator iterator= comment.tags().iterator(); iterator.hasNext();) {
				tag= (ASTNode) iterator.next();
				if (!tags.contains(tag))
					rewriter.remove(tag, null);
			}
			for (final Iterator iterator= arguments.iterator(); iterator.hasNext();) {
				tag= (ASTNode) iterator.next();
				if (reference != null)
					rewriter.insertBefore(tag, reference, null);
				else
					rewriter.insertLast(tag, null);
			}
		}
	}

	/**
	 * Creates the method content of the moved method.
	 * 
	 * @param document
	 *            the document representing the source compilation unit
	 * @param declaration
	 *            the source method declaration
	 * @param rewrite
	 *            the ast rewrite to use
	 * @return the string representing the moved method body
	 * @throws BadLocationException
	 *             if an offset into the document is invalid
	 */
	protected String createMethodContent(final IDocument document, final FunctionDeclaration declaration, final ASTRewrite rewrite) throws BadLocationException {
		Assert.isNotNull(document);
		Assert.isNotNull(declaration);
		Assert.isNotNull(rewrite);
		final IRegion range= new Region(declaration.getStartPosition(), declaration.getLength());
		final RangeMarker marker= new RangeMarker(range.getOffset(), range.getLength());
		final IJavaScriptProject project= fMethod.getJavaScriptProject();
		final TextEdit[] edits= rewrite.rewriteAST(document, project.getOptions(true)).removeChildren();
		for (int index= 0; index < edits.length; index++)
			marker.addChild(edits[index]);
		final MultiTextEdit result= new MultiTextEdit();
		result.addChild(marker);
		final TextEditProcessor processor= new TextEditProcessor(document, new MultiTextEdit(0, document.getLength()), TextEdit.UPDATE_REGIONS);
		processor.getRoot().addChild(result);
		processor.performEdits();
		final IRegion region= document.getLineInformation(document.getLineOfOffset(marker.getOffset()));
		return Strings.changeIndent(document.get(marker.getOffset(), marker.getLength()), Strings.computeIndentUnits(document.get(region.getOffset(), region.getLength()), project), project, "", TextUtilities.getDefaultLineDelimiter(document)); //$NON-NLS-1$
	}

	/**
	 * Creates the necessary changes to create the delegate method with the
	 * original method body.
	 * 
	 * @param document
	 *            the buffer containing the source of the source compilation
	 *            unit
	 * @param declaration
	 *            the method declaration to use as source
	 * @param rewrite
	 *            the ast rewrite to use for the copy of the method body
	 * @param rewrites
	 *            the compilation unit rewrites
	 * @param adjustments
	 *            the map of elements to visibility adjustments
	 * @param status
	 *            the refactoring status
	 * @param monitor
	 *            the progress monitor to display progress
	 * @throws CoreException
	 *             if an error occurs
	 * @return <code>true</code> if a target node had to be inserted as first
	 *         argument, <code>false</code> otherwise
	 */
	protected boolean createMethodCopy(final IDocument document, final FunctionDeclaration declaration, final ASTRewrite rewrite, final Map rewrites, final Map adjustments, final RefactoringStatus status, final IProgressMonitor monitor) throws CoreException {
		Assert.isNotNull(document);
		Assert.isNotNull(declaration);
		Assert.isNotNull(rewrite);
		Assert.isNotNull(rewrites);
		Assert.isNotNull(adjustments);
		Assert.isNotNull(status);
		Assert.isNotNull(monitor);
		boolean target= false;
		final CompilationUnitRewrite rewriter= getCompilationUnitRewrite(rewrites, getTargetType().getJavaScriptUnit());
		try {
			rewrite.set(declaration, FunctionDeclaration.NAME_PROPERTY, rewrite.getAST().newSimpleName(fMethodName), null);
			boolean same= false;
			final IFunctionBinding binding= declaration.resolveBinding();
			if (binding != null) {
				final ITypeBinding declaring= binding.getDeclaringClass();
				if (declaring != null && Bindings.equals(declaring.getPackage(), fTarget.getType().getPackage()))
					same= true;
				final Modifier.ModifierKeyword keyword= same ? null : Modifier.ModifierKeyword.PUBLIC_KEYWORD;
				if (MemberVisibilityAdjustor.hasLowerVisibility(binding.getModifiers(), same ? Modifier.NONE : (keyword == null ? Modifier.NONE : keyword.toFlagValue())) && MemberVisibilityAdjustor.needsVisibilityAdjustments(fMethod, keyword, adjustments)) {
					final MemberVisibilityAdjustor.IncomingMemberVisibilityAdjustment adjustment= new MemberVisibilityAdjustor.IncomingMemberVisibilityAdjustment(fMethod, keyword, RefactoringStatus.createStatus(RefactoringStatus.WARNING, Messages.format(RefactoringCoreMessages.MemberVisibilityAdjustor_change_visibility_method_warning, new String[] { MemberVisibilityAdjustor.getLabel(fMethod), MemberVisibilityAdjustor.getLabel(keyword) }), JavaStatusContext.create(fMethod), null, RefactoringStatusEntry.NO_CODE, null));
					ModifierRewrite.create(rewrite, declaration).setVisibility(keyword == null ? Modifier.NONE : keyword.toFlagValue(), null);
					adjustment.setNeedsRewriting(false);
					adjustments.put(fMethod, adjustment);
				}
			}
			target= createMethodArguments(rewrites, rewrite, declaration, adjustments, status);
			createMethodTypeParameters(rewrite, declaration, status);
			createMethodComment(rewrite, declaration);
			createMethodBody(rewriter, rewrite, declaration);
		} finally {
			if (fMethod.getJavaScriptUnit().equals(getTargetType().getJavaScriptUnit()))
				rewriter.clearImportRewrites();
		}
		return target;
	}

	/**
	 * Creates the necessary changes to replace the body of the method
	 * declaration with an expression to invoke the delegate.
	 * 
	 * @param declaration
	 *            the method declaration to replace its body
	 * @param rewrites
	 *            the compilation unit rewrites
	 * @param adjustments
	 *            the map of elements to visibility adjustments
	 * @param status
	 *            the refactoring status
	 * @param monitor
	 *            the progress monitor to display progress
	 * @throws CoreException
	 *             if the change could not be generated
	 * @return <code>true</code> if a target node had to be inserted as first
	 *         argument, <code>false</code> otherwise
	 */
	protected boolean createMethodDelegation(final FunctionDeclaration declaration, final Map rewrites, final Map adjustments, final RefactoringStatus status, final IProgressMonitor monitor) throws CoreException {
		Assert.isNotNull(declaration);
		Assert.isNotNull(monitor);

		final DelegateInstanceMethodCreator creator= new DelegateInstanceMethodCreator(adjustments, rewrites);
		creator.setSourceRewrite(fSourceRewrite);
		creator.setCopy(false);
		creator.setDeclareDeprecated(fDelegateDeprecation);
		creator.setDeclaration(declaration);
		creator.setNewElementName(fMethodName);
		creator.prepareDelegate();
		creator.createEdit();

		return creator.getNeededInsertion();
	}

	/**
	 * Creates the necessary changes to inline the method invocations to the
	 * original method.
	 * 
	 * @param rewrites
	 *            the map of compilation units to compilation unit rewrites
	 * @param declaration
	 *            the source method declaration
	 * @param groups
	 *            the search result groups representing all references to the
	 *            moved method, including references in comments
	 * @param adjustments
	 *            the map of elements to visibility adjustments
	 * @param target
	 *            <code>true</code> if a target node must be inserted as first
	 *            argument, <code>false</code> otherwise
	 * @param status
	 *            the refactoring status
	 * @param monitor
	 *            the progress monitor to use
	 * @return <code>true</code> if all method invocations to the original
	 *         method declaration could be inlined, <code>false</code>
	 *         otherwise
	 */
	protected boolean createMethodDelegator(final Map rewrites, final FunctionDeclaration declaration, final SearchResultGroup[] groups, final Map adjustments, final boolean target, final RefactoringStatus status, final IProgressMonitor monitor) {
		Assert.isNotNull(rewrites);
		Assert.isNotNull(declaration);
		Assert.isNotNull(groups);
		Assert.isNotNull(adjustments);
		Assert.isNotNull(status);
		Assert.isNotNull(monitor);
		try {
			monitor.beginTask("", groups.length); //$NON-NLS-1$
			monitor.setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_creating);
			try {
				boolean result= true;
				boolean found= false;
				final ITypeHierarchy hierarchy= fMethod.getDeclaringType().newTypeHierarchy(new SubProgressMonitor(monitor, 1));
				IType type= null;
				IFunction method= null;
				IType[] types= hierarchy.getAllSubtypes(fMethod.getDeclaringType());
				for (int index= 0; index < types.length && !found; index++) {
					type= types[index];
					method= JavaModelUtil.findMethod(fMethod.getElementName(), fMethod.getParameterTypes(), false, type);
					if (method != null)
						found= true;
				}
				types= hierarchy.getAllSupertypes(fMethod.getDeclaringType());
				for (int index= 0; index < types.length && !found; index++) {
					type= types[index];
					method= JavaModelUtil.findMethod(fMethod.getElementName(), fMethod.getParameterTypes(), false, type);
					if (method != null)
						found= true;
				}
				if (found) {
					status.merge(RefactoringStatus.createWarningStatus(Messages.format(RefactoringCoreMessages.MoveInstanceMethodProcessor_inline_overridden, BindingLabelProvider.getBindingLabel(declaration.resolveBinding(), JavaScriptElementLabels.ALL_FULLY_QUALIFIED)), JavaStatusContext.create(fMethod)));
					result= false;
				} else {
					monitor.worked(1);
					SearchMatch[] matches= null;
					IJavaScriptElement element= null;
					IJavaScriptUnit unit= null;
					CompilationUnitRewrite rewrite= null;
					SearchResultGroup group= null;
					for (int index= 0; index < groups.length; index++) {
						group= groups[index];
						element= JavaScriptCore.create(group.getResource());
						if (element instanceof IJavaScriptUnit) {
							matches= group.getSearchResults();
							unit= (IJavaScriptUnit) element;
							rewrite= getCompilationUnitRewrite(rewrites, unit);
							SearchMatch match= null;
							for (int offset= 0; offset < matches.length; offset++) {
								match= matches[offset];
								if (match.getAccuracy() == SearchMatch.A_INACCURATE) {
									status.merge(RefactoringStatus.createWarningStatus(Messages.format(RefactoringCoreMessages.MoveInstanceMethodProcessor_inline_inaccurate, unit.getCorrespondingResource().getName()), JavaStatusContext.create(unit, new SourceRange(match.getOffset(), match.getLength()))));
									result= false;
								} else if (!createInlinedMethodInvocation(rewrite, declaration, match, adjustments, target, status))
									result= false;
							}
						} else if (element != null) {
							status.merge(RefactoringStatus.createWarningStatus(Messages.format(RefactoringCoreMessages.MoveInstanceMethodProcessor_inline_binary_project, element.getJavaScriptProject().getElementName())));
							result= false;
						} else {
							status.merge(RefactoringStatus.createWarningStatus(Messages.format(RefactoringCoreMessages.MoveInstanceMethodProcessor_inline_binary_resource, group.getResource().getName())));
							result= false;
						}
					}
					monitor.worked(1);
				}
				return result;
			} catch (CoreException exception) {
				status.merge(RefactoringStatus.create(exception.getStatus()));
				return false;
			}
		} finally {
			monitor.done();
		}
	}

	/**
	 * Creates the necessary imports for the copied method in the target
	 * compilation unit.
	 * 
	 * @param rewrite
	 *            the target compilation unit rewrite
	 * @param declaration
	 *            the source method declaration
	 * @param monitor
	 *            the progress monitor to use
	 * @param status
	 *            the refactoring status to use
	 * @throws CoreException
	 *             if an error occurs
	 */
	protected void createMethodImports(final CompilationUnitRewrite rewrite, final FunctionDeclaration declaration, final IProgressMonitor monitor, final RefactoringStatus status) throws CoreException {
		Assert.isNotNull(rewrite);
		Assert.isNotNull(declaration);
		Assert.isNotNull(monitor);
		Assert.isNotNull(status);
		monitor.beginTask("", 1); //$NON-NLS-1$
		monitor.setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_creating);
		try {
			ImportRewriteUtil.addImports(rewrite, declaration, new HashMap(), new HashMap(), false);
		} finally {
			monitor.done();
		}
	}

	/**
	 * Creates the necessary change to updated a comment reference represented
	 * by a search match.
	 * 
	 * @param rewrite
	 *            the current compilation unit rewrite
	 * @param declaration
	 *            the source method declaration
	 * @param match
	 *            the search match representing the method reference
	 * @param targetNode
	 *            <code>true</code> if a target node had to be inserted as
	 *            first argument, <code>false</code> otherwise
	 * @param status
	 *            the refactoring status
	 */
	protected void createMethodJavadocReference(final CompilationUnitRewrite rewrite, final FunctionDeclaration declaration, final SearchMatch match, final boolean targetNode, final RefactoringStatus status) {
		Assert.isNotNull(rewrite);
		Assert.isNotNull(declaration);
		Assert.isNotNull(match);
		Assert.isNotNull(status);
		final ASTNode node= ASTNodeSearchUtil.findNode(match, rewrite.getRoot());
		if (node instanceof FunctionRef) {
			final AST ast= node.getAST();
			final FunctionRef successor= ast.newFunctionRef();

			rewrite.getASTRewrite().replace(node, successor, null);
		}
	}

	/**
	 * Creates the necessary changes to update tag references to the original
	 * method.
	 * 
	 * @param rewrites
	 *            the map of compilation units to compilation unit rewrites
	 * @param declaration
	 *            the source method declaration
	 * @param groups
	 *            the search result groups representing all references to the
	 *            moved method, including references in comments
	 * @param target
	 *            <code>true</code> if a target node must be inserted as first
	 *            argument, <code>false</code> otherwise
	 * @param status
	 *            the refactoring status
	 * @param monitor
	 *            the progress monitor to use
	 */
	protected void createMethodJavadocReferences(final Map rewrites, final FunctionDeclaration declaration, final SearchResultGroup[] groups, final boolean target, final RefactoringStatus status, final IProgressMonitor monitor) {
		Assert.isNotNull(rewrites);
		Assert.isNotNull(declaration);
		Assert.isNotNull(status);
		Assert.isNotNull(monitor);
		try {
			monitor.beginTask("", groups.length); //$NON-NLS-1$
			monitor.setTaskName(RefactoringCoreMessages.MoveInstanceMethodProcessor_creating);
			try {
				SearchMatch[] matches= null;
				IJavaScriptElement element= null;
				IJavaScriptUnit unit= null;
				CompilationUnitRewrite rewrite= null;
				SearchResultGroup group= null;
				for (int index= 0; index < groups.length; index++) {
					group= groups[index];
					element= JavaScriptCore.create(group.getResource());
					unit= group.getCompilationUnit();
					if (element instanceof IJavaScriptUnit) {
						matches= group.getSearchResults();
						unit= (IJavaScriptUnit) element;
						rewrite= getCompilationUnitRewrite(rewrites, unit);
						SearchMatch match= null;
						for (int offset= 0; offset < matches.length; offset++) {
							match= matches[offset];
							if (match.getAccuracy() == SearchMatch.A_INACCURATE) {
								status.merge(RefactoringStatus.createWarningStatus(Messages.format(RefactoringCoreMessages.MoveInstanceMethodProcessor_inline_inaccurate, unit.getCorrespondingResource().getName()), JavaStatusContext.create(unit, new SourceRange(match.getOffset(), match.getLength()))));
							} else
								createMethodJavadocReference(rewrite, declaration, match, target, status);
						}
					} else if (element != null) {
						status.merge(RefactoringStatus.createWarningStatus(Messages.format(RefactoringCoreMessages.MoveInstanceMethodProcessor_javadoc_binary_project, element.getJavaScriptProject().getElementName())));
					} else {
						status.merge(RefactoringStatus.createWarningStatus(Messages.format(RefactoringCoreMessages.MoveInstanceMethodProcessor_javadoc_binary_resource, group.getResource().getName())));
					}
					monitor.worked(1);
				}
			} catch (CoreException exception) {
				status.merge(RefactoringStatus.create(exception.getStatus()));
			}
		} finally {
			monitor.done();
		}
	}

	/**
	 * Creates a comment method reference to the moved method
	 * 
	 * @param declaration
	 *            the method declaration of the original method
	 * @param ast
	 *            the ast to create the method reference for
	 * @return the created link tag to reference the method
	 * @throws JavaScriptModelException
	 *             if an error occurs
	 */
	protected ASTNode createMethodReference(final FunctionDeclaration declaration, final AST ast) throws JavaScriptModelException {
		Assert.isNotNull(ast);
		Assert.isNotNull(declaration);
		final FunctionRef reference= ast.newFunctionRef();
		reference.setName(ast.newSimpleName(fMethodName));
		reference.setQualifier(ASTNodeFactory.newName(ast, JavaModelUtil.getFullyQualifiedName(fTargetType)));
		createArgumentList(declaration, reference.parameters(), new IArgumentFactory() {

			public final ASTNode getArgumentNode(final IVariableBinding binding, final boolean last) {
				Assert.isNotNull(binding);
				final FunctionRefParameter parameter= ast.newFunctionRefParameter();
				parameter.setType(ASTNodeFactory.newType(ast, binding.getType().getName()));
				return parameter;
			}

			public final ASTNode getTargetNode() {
				final FunctionRefParameter parameter= ast.newFunctionRefParameter();
				final IFunctionBinding method= declaration.resolveBinding();
				if (method != null) {
					final ITypeBinding declaring= method.getDeclaringClass();
					if (declaring != null)
						parameter.setType(ASTNodeFactory.newType(ast, Bindings.getFullyQualifiedName(declaring)));
				}
				return parameter;
			}
		});
		return reference;
	}

	/**
	 * @param document
	 *            the buffer containing the source of the source compilation
	 *            unit
	 * @param declaration
	 *            the method declaration to use as source
	 * @param rewrite
	 *            the ast rewrite to use for the copy of the method body
	 * @param rewrites
	 *            the compilation unit rewrites
	 * @throws JavaScriptModelException
	 *             if the insertion point cannot be found
	 */
	protected void createMethodSignature(final IDocument document, final FunctionDeclaration declaration, final ASTRewrite rewrite, final Map rewrites) throws JavaScriptModelException {
		Assert.isNotNull(document);
		Assert.isNotNull(declaration);
		Assert.isNotNull(rewrite);
		Assert.isNotNull(rewrites);
		try {
			final CompilationUnitRewrite rewriter= getCompilationUnitRewrite(rewrites, getTargetType().getJavaScriptUnit());
			final FunctionDeclaration stub= (FunctionDeclaration) rewriter.getASTRewrite().createStringPlaceholder(createMethodContent(document, declaration, rewrite), ASTNode.FUNCTION_DECLARATION);
			final AbstractTypeDeclaration type= ASTNodeSearchUtil.getAbstractTypeDeclarationNode(getTargetType(), rewriter.getRoot());
			rewriter.getASTRewrite().getListRewrite(type, type.getBodyDeclarationsProperty()).insertAt(stub, ASTNodes.getInsertionIndex(stub, type.bodyDeclarations()), rewriter.createGroupDescription(RefactoringCoreMessages.MoveInstanceMethodProcessor_add_moved_method));
		} catch (BadLocationException exception) {
			JavaScriptPlugin.log(exception);
		}
	}

	/**
	 * Creates the necessary changes to remove method type parameters if they
	 * match with enclosing type parameters.
	 * 
	 * @param rewrite
	 *            the ast rewrite to use
	 * @param declaration
	 *            the method declaration to remove type parameters
	 * @param status
	 *            the refactoring status
	 */
	protected void createMethodTypeParameters(final ASTRewrite rewrite, final FunctionDeclaration declaration, final RefactoringStatus status) {
		ITypeBinding binding= fTarget.getType();
		if (binding != null && binding.isParameterizedType()) {
			final IFunctionBinding method= declaration.resolveBinding();
			if (method != null) {
				final ITypeBinding[] parameters= method.getTypeParameters();
				if (parameters.length > 0) {
					final ListRewrite rewriter= rewrite.getListRewrite(declaration, FunctionDeclaration.TYPE_PARAMETERS_PROPERTY);
					boolean foundStatic= false;
					while (binding != null && !foundStatic) {
						if (Flags.isStatic(binding.getModifiers()))
							foundStatic= true;
						final ITypeBinding[] bindings= binding.getTypeArguments();
						for (int index= 0; index < bindings.length; index++) {
							for (int offset= 0; offset < parameters.length; offset++) {
								if (parameters[offset].getName().equals(bindings[index].getName())) {
									rewriter.remove((ASTNode) rewriter.getOriginalList().get(offset), null);
									status.addWarning(Messages.format(RefactoringCoreMessages.MoveInstanceMethodProcessor_present_type_parameter_warning, new Object[] { parameters[offset].getName(), BindingLabelProvider.getBindingLabel(binding, JavaScriptElementLabels.ALL_FULLY_QUALIFIED) }), JavaStatusContext.create(fMethod));
								}
							}
						}
						binding= binding.getDeclaringClass();
					}
				}
			}
		}
	}

	/**
	 * Creates the expression to access the new target.
	 * 
	 * @param declaration
	 *            the method declaration where to access the target
	 * @return the corresponding expression
	 */
	protected Expression createSimpleTargetAccessExpression(final FunctionDeclaration declaration) {
		Assert.isNotNull(declaration);
		Expression expression= null;
		final AST ast= declaration.getAST();
		final ITypeBinding type= fTarget.getDeclaringClass();
		if (type != null) {
			boolean shadows= false;
			final IVariableBinding[] bindings= getArgumentBindings(declaration);
			IVariableBinding variable= null;
			for (int index= 0; index < bindings.length; index++) {
				variable= bindings[index];
				if (fMethod.getDeclaringType().getField(variable.getName()).exists()) {
					shadows= true;
					break;
				}
			}
			if (fSettings.useKeywordThis || shadows) {
				final FieldAccess access= ast.newFieldAccess();
				access.setName(ast.newSimpleName(fTarget.getName()));
				access.setExpression(ast.newThisExpression());
				expression= access;
			} else
				expression= ast.newSimpleName(fTarget.getName());
		} else
			expression= ast.newSimpleName(fTarget.getName());
		return expression;
	}

	/**
	 * Returns the candidate targets for the method to move.
	 * 
	 * @return the candidate targets as variable bindings of fields and
	 *         parameters
	 */
	public final IVariableBinding[] getCandidateTargets() {
		Assert.isNotNull(fCandidateTargets);
		return fCandidateTargets;
	}

	/**
	 * {@inheritDoc}
	 */
	public String getComment() {
		return fComment;
	}

	/**
	 * Returns a compilation unit rewrite for the specified compilation unit.
	 * 
	 * @param rewrites
	 *            the compilation unit rewrite map
	 * @param unit
	 *            the compilation unit
	 * @return the corresponding compilation unit rewrite
	 */
	protected CompilationUnitRewrite getCompilationUnitRewrite(final Map rewrites, final IJavaScriptUnit unit) {
		Assert.isNotNull(rewrites);
		Assert.isNotNull(unit);
		CompilationUnitRewrite rewrite= (CompilationUnitRewrite) rewrites.get(unit);
		if (rewrite == null) {
			rewrite= new CompilationUnitRewrite(unit);
			rewrites.put(unit, rewrite);
		}
		return rewrite;
	}

	/**
	 * {@inheritDoc}
	 */
	public final boolean getDelegateUpdating() {
		return fDelegatingUpdating;
	}

	/**
	 * {@inheritDoc}
	 */
	public String getDelegateUpdatingTitle(boolean plural) {
		if (plural)
			return RefactoringCoreMessages.DelegateMethodCreator_keep_original_moved_plural;
		else
			return RefactoringCoreMessages.DelegateMethodCreator_keep_original_moved_singular;
	}

	/**
	 * {@inheritDoc}
	 */
	public final boolean getDeprecateDelegates() {
		return fDelegateDeprecation;
	}

	/**
	 * {@inheritDoc}
	 */
	public final Object[] getElements() {
		return new Object[] { fMethod };
	}

	/**
	 * {@inheritDoc}
	 */
	public final String getIdentifier() {
		return IDENTIFIER;
	}

	/**
	 * Returns the method to be moved.
	 * 
	 * @return the method to be moved
	 */
	public final IFunction getMethod() {
		return fMethod;
	}

	/**
	 * Returns the new method name.
	 * 
	 * @return the name of the new method
	 */
	public final String getMethodName() {
		return fMethodName;
	}

	/**
	 * Returns the possible targets for the method to move.
	 * 
	 * @return the possible targets as variable bindings of read-only fields and
	 *         parameters
	 */
	public final IVariableBinding[] getPossibleTargets() {
		Assert.isNotNull(fPossibleTargets);
		return fPossibleTargets;
	}

	/*
	 * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor#getProcessorName()
	 */
	public final String getProcessorName() {
		return RefactoringCoreMessages.MoveInstanceMethodProcessor_name;
	}

	/**
	 * Returns the index of the chosen target.
	 * 
	 * @return the target index
	 */
	protected final int getTargetIndex() {
		final IVariableBinding[] targets= getPossibleTargets();
		int result= -1;
		for (int index= 0; index < targets.length; index++) {
			if (Bindings.equals(fTarget, targets[index])) {
				result= index;
				break;
			}
		}
		return result;
	}

	/**
	 * Returns the new target name.
	 * 
	 * @return the name of the new target
	 */
	public final String getTargetName() {
		return fTargetName;
	}

	/**
	 * Returns the type of the new target.
	 * 
	 * @return the type of the new target
	 * @throws JavaScriptModelException
	 *             if the type does not exist
	 */
	protected IType getTargetType() throws JavaScriptModelException {
		Assert.isNotNull(fTarget);
		if (fTargetType == null) {
			final ITypeBinding binding= fTarget.getType();
			if (binding != null)
				fTargetType= (IType) binding.getJavaElement();
			else
				throw new JavaScriptModelException(new CoreException(new Status(IStatus.ERROR, JavaScriptPlugin.getPluginId(), 0, RefactoringCoreMessages.MoveInstanceMethodProcessor_cannot_be_moved, null)));
		}
		return fTargetType;
	}

	/**
	 * Initializes the refactoring with the given input.
	 * 
	 * @param method
	 *            the method to move
	 */
	protected void initialize(final IFunction method) {
		Assert.isNotNull(method);
		fSourceRewrite= new CompilationUnitRewrite(fMethod.getJavaScriptUnit());
		fMethodName= method.getElementName();
		fTargetName= suggestTargetName();
		if (fSettings == null)
			fSettings= JavaPreferencesSettings.getCodeGenerationSettings(fMethod.getJavaScriptProject());
	}

	/**
	 * {@inheritDoc}
	 */
	public RefactoringStatus initialize(final RefactoringArguments arguments) {
		if (arguments instanceof JavaRefactoringArguments) {
			final JavaRefactoringArguments extended= (JavaRefactoringArguments) arguments;
			final String handle= extended.getAttribute(JDTRefactoringDescriptor.ATTRIBUTE_INPUT);
			if (handle != null) {
				final IJavaScriptElement element= JDTRefactoringDescriptor.handleToElement(extended.getProject(), handle, false);
				if (element == null || !element.exists() || element.getElementType() != IJavaScriptElement.METHOD)
					return ScriptableRefactoring.createInputFatalStatus(element, getRefactoring().getName(), IJavaScriptRefactorings.MOVE_METHOD);
				else {
					fMethod= (IFunction) element;
					initialize(fMethod);
				}
			} else
				return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, JDTRefactoringDescriptor.ATTRIBUTE_INPUT));
			final String name= extended.getAttribute(JDTRefactoringDescriptor.ATTRIBUTE_NAME);
			if (name != null) {
				final RefactoringStatus status= setMethodName(name);
				if (status.hasError())
					return status;
			} else
				return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, JDTRefactoringDescriptor.ATTRIBUTE_NAME));
			final String deprecate= extended.getAttribute(ATTRIBUTE_DEPRECATE);
			if (deprecate != null) {
				fDelegateDeprecation= Boolean.valueOf(deprecate).booleanValue();
			} else
				return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_DEPRECATE));
			final String remove= extended.getAttribute(ATTRIBUTE_REMOVE);
			if (remove != null) {
				fRemove= Boolean.valueOf(remove).booleanValue();
			} else
				return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_REMOVE));
			final String inline= extended.getAttribute(ATTRIBUTE_INLINE);
			if (inline != null) {
				fInline= Boolean.valueOf(inline).booleanValue();
			} else
				return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_INLINE));
			final String getter= extended.getAttribute(ATTRIBUTE_USE_GETTER);
			if (getter != null)
				fUseGetters= Boolean.valueOf(getter).booleanValue();
			else
				return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_USE_GETTER));
			final String setter= extended.getAttribute(ATTRIBUTE_USE_SETTER);
			if (setter != null)
				fUseSetters= Boolean.valueOf(setter).booleanValue();
			else
				return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_USE_SETTER));
			final String target= extended.getAttribute(ATTRIBUTE_TARGET_NAME);
			if (target != null) {
				final RefactoringStatus status= setTargetName(target);
				if (status.hasError())
					return status;
			} else
				return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_TARGET_NAME));
			final String value= extended.getAttribute(ATTRIBUTE_TARGET_INDEX);
			if (value != null) {
				try {
					final int index= Integer.valueOf(value).intValue();
					if (index >= 0) {
						final FunctionDeclaration declaration= ASTNodeSearchUtil.getMethodDeclarationNode(fMethod, fSourceRewrite.getRoot());
						if (declaration != null) {
							final IVariableBinding[] bindings= computeTargetCategories(declaration);
							if (bindings != null && index < bindings.length)
								setTarget(bindings[index]);
						}
					}
				} catch (NumberFormatException exception) {
					return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_illegal_argument, new String[] { value, ATTRIBUTE_TARGET_INDEX }));
				} catch (JavaScriptModelException exception) {
					return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_illegal_argument, new String[] { value, ATTRIBUTE_TARGET_INDEX }));
				}
			} else
				return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_TARGET_INDEX));
		} else
			return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.InitializableRefactoring_inacceptable_arguments);
		return new RefactoringStatus();
	}

	/*
	 * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor#isApplicable()
	 */
	public final boolean isApplicable() throws CoreException {
		return fMethod.exists() && !fMethod.isConstructor() && !fMethod.isBinary() && !fMethod.isReadOnly() && fMethod.getJavaScriptUnit() != null && !JdtFlags.isStatic(fMethod);
	}

	/**
	 * Is the specified name a target access?
	 * 
	 * @param name
	 *            the name to check
	 * @return <code>true</code> if this name is a target access,
	 *         <code>false</code> otherwise
	 */
	protected boolean isTargetAccess(final Name name) {
		Assert.isNotNull(name);
		final IBinding binding= name.resolveBinding();
		if (Bindings.equals(fTarget, binding))
			return true;
		if (name.getParent() instanceof FieldAccess) {
			final FieldAccess access= (FieldAccess) name.getParent();
			final Expression expression= access.getExpression();
			if (expression instanceof Name)
				return isTargetAccess((Name) expression);
		} else if (name instanceof QualifiedName) {
			final QualifiedName qualified= (QualifiedName) name;
			if (qualified.getQualifier() != null)
				return isTargetAccess(qualified.getQualifier());
		}
		return false;
	}

	/*
	 * @see org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor#loadParticipants(org.eclipse.ltk.core.refactoring.RefactoringStatus,
	 *      org.eclipse.ltk.core.refactoring.participants.SharableParticipants)
	 */
	public final RefactoringParticipant[] loadParticipants(final RefactoringStatus status, final SharableParticipants participants) throws CoreException {
		return new RefactoringParticipant[0];
	}

	/**
	 * Does the moved method need a target node?
	 * 
	 * @return <code>true</code> if it needs a target node, <code>false</code>
	 *         otherwise
	 */
	public final boolean needsTargetNode() {
		return fTargetNode;
	}

	/**
	 * {@inheritDoc}
	 */
	public void setComment(final String comment) {
		fComment= comment;
	}

	/**
	 * {@inheritDoc}
	 */
	public final void setDelegateUpdating(final boolean updating) {
		fDelegatingUpdating= updating;
		setInlineDelegator(!updating);
		setRemoveDelegator(!updating);
	}

	/**
	 * {@inheritDoc}
	 */
	public final void setDeprecateDelegates(final boolean deprecate) {
		fDelegateDeprecation= deprecate;
	}

	/**
	 * Determines whether the delegator has to be inlined.
	 * 
	 * @param inline
	 *            <code>true</code> to inline the delegator,
	 *            <code>false</code> otherwise
	 */
	public final void setInlineDelegator(final boolean inline) {
		fInline= inline;
	}

	/**
	 * Sets the new method name.
	 * 
	 * @param name
	 *            the name to set
	 * @return the status of the operation
	 */
	public final RefactoringStatus setMethodName(final String name) {
		Assert.isNotNull(name);
		RefactoringStatus status= Checks.checkMethodName(name);
		if (status.hasFatalError())
			return status;
		fMethodName= name;
		return status;
	}

	/**
	 * Determines whether the delegator has to be removed after inlining. Note
	 * that the option to inline the delegator has to be enabled if this method
	 * is called with the argument <code>true</code>.
	 * 
	 * @param remove
	 *            <code>true</code> if it should be removed,
	 *            <code>false</code> otherwise
	 */
	public final void setRemoveDelegator(final boolean remove) {
		Assert.isTrue(!remove || fInline);
		fRemove= remove;
	}

	/**
	 * Sets the new target.
	 * 
	 * @param target
	 *            the target to set
	 */
	public final void setTarget(final IVariableBinding target) {
		Assert.isNotNull(target);
		fTarget= target;
		fTargetType= null;
		try {
			final FunctionDeclaration declaration= ASTNodeSearchUtil.getMethodDeclarationNode(fMethod, fSourceRewrite.getRoot());
			if (declaration != null) {
				final AstNodeFinder finder= new ThisReferenceFinder();
				declaration.accept(finder);
				fTargetNode= !finder.getResult().isEmpty();
				return;
			}
		} catch (JavaScriptModelException exception) {
			JavaScriptPlugin.log(exception);
		}
		fTargetNode= true;
	}

	/**
	 * Sets the new target name.
	 * 
	 * @param name
	 *            the name to set
	 * @return the status of the operation
	 */
	public final RefactoringStatus setTargetName(final String name) {
		Assert.isNotNull(name);
		final RefactoringStatus status= Checks.checkTempName(name);
		if (status.hasFatalError())
			return status;
		fTargetName= name;
		return status;
	}

	/**
	 * Determines whether getter methods should be used to resolve visibility
	 * issues.
	 * 
	 * @param use
	 *            <code>true</code> if getter methods should be used,
	 *            <code>false</code> otherwise
	 */
	public final void setUseGetters(final boolean use) {
		fUseGetters= use;
	}

	/**
	 * Determines whether setter methods should be used to resolve visibility
	 * issues.
	 * 
	 * @param use
	 *            <code>true</code> if setter methods should be used,
	 *            <code>false</code> otherwise
	 */
	public final void setUseSetters(final boolean use) {
		fUseSetters= use;
	}

	/**
	 * Should getter methods be used to resolve visibility issues?
	 * 
	 * @return <code>true</code> if getter methods should be used,
	 *         <code>false</code> otherwise
	 */
	public final boolean shouldUseGetters() {
		return fUseGetters;
	}

	/**
	 * Should setter methods be used to resolve visibility issues?
	 * 
	 * @return <code>true</code> if setter methods should be used,
	 *         <code>false</code> otherwise
	 */
	public final boolean shouldUseSetters() {
		return fUseSetters;
	}

	/**
	 * Returns a best guess for the name of the new target.
	 * 
	 * @return a best guess for the name
	 */
	protected String suggestTargetName() {
		try {

			final String[] candidates= StubUtility.getArgumentNameSuggestions(fMethod.getDeclaringType(),fMethod.getJavaScriptUnit(), computeReservedIdentifiers());
			if (candidates.length > 0) {
				if (candidates[0].indexOf('$') < 0)
					return candidates[0];
			}
		} catch (JavaScriptModelException exception) {
			JavaScriptPlugin.log(exception);
		}
		return "arg"; //$NON-NLS-1$
	}
}
