/*******************************************************************************
 * Copyright (c) 2000, 2010 IBM Corporation and others.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 * 
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Benjamin Muskalla <bmuskalla@eclipsesource.com> - [extract method] Does not replace similar code in parent class of anonymous class - https://bugs.eclipse.org/bugs/show_bug.cgi?id=160853
 *     Benjamin Muskalla <bmuskalla@eclipsesource.com> - [extract method] Extract method and continue https://bugs.eclipse.org/bugs/show_bug.cgi?id=48056
 *     Benjamin Muskalla <bmuskalla@eclipsesource.com> - [extract method] should declare method static if extracted from anonymous in static method - https://bugs.eclipse.org/bugs/show_bug.cgi?id=152004
 *******************************************************************************/
package org.eclipse.dltk.internal.javascript.corext.refactoring.code;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.dltk.core.IScriptProject;
import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.dltk.core.manipulation.RefactoringChecks;
import org.eclipse.dltk.core.manipulation.SourceModuleChange;
import org.eclipse.dltk.internal.corext.refactoring.ScriptRefactoringDescriptor;
import org.eclipse.dltk.internal.corext.refactoring.util.ResourceUtil;
import org.eclipse.dltk.internal.javascript.core.manipulation.Messages;
import org.eclipse.dltk.internal.javascript.corext.refactoring.Checks;
import org.eclipse.dltk.internal.javascript.corext.refactoring.ParameterInfo;
import org.eclipse.dltk.internal.javascript.corext.refactoring.RefactoringCoreMessages;
import org.eclipse.dltk.internal.javascript.corext.refactoring.code.flow.VariableBinding;
import org.eclipse.dltk.internal.javascript.corext.refactoring.util.Selection;
import org.eclipse.dltk.javascript.core.dom.BinaryExpression;
import org.eclipse.dltk.javascript.core.dom.BinaryOperator;
import org.eclipse.dltk.javascript.core.dom.BlockStatement;
import org.eclipse.dltk.javascript.core.dom.CallExpression;
import org.eclipse.dltk.javascript.core.dom.DomFactory;
import org.eclipse.dltk.javascript.core.dom.DomPackage;
import org.eclipse.dltk.javascript.core.dom.Expression;
import org.eclipse.dltk.javascript.core.dom.ExpressionStatement;
import org.eclipse.dltk.javascript.core.dom.FunctionExpression;
import org.eclipse.dltk.javascript.core.dom.Identifier;
import org.eclipse.dltk.javascript.core.dom.Node;
import org.eclipse.dltk.javascript.core.dom.Parameter;
import org.eclipse.dltk.javascript.core.dom.ReturnStatement;
import org.eclipse.dltk.javascript.core.dom.Source;
import org.eclipse.dltk.javascript.core.dom.Statement;
import org.eclipse.dltk.javascript.core.dom.VariableDeclaration;
import org.eclipse.dltk.javascript.core.dom.VariableReference;
import org.eclipse.dltk.javascript.core.dom.VariableStatement;
import org.eclipse.dltk.javascript.core.dom.rewrite.ASTConverter;
import org.eclipse.dltk.javascript.core.dom.rewrite.Generator;
import org.eclipse.dltk.javascript.core.dom.rewrite.RewriteAnalyzer;
import org.eclipse.dltk.javascript.core.dom.rewrite.VariableLookup;
import org.eclipse.dltk.javascript.core.refactoring.descriptors.ExtractMethodDescriptor;
import org.eclipse.dltk.javascript.parser.JavaScriptParserUtil;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.change.ChangeDescription;
import org.eclipse.emf.ecore.change.util.ChangeRecorder;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.Refactoring;
import org.eclipse.ltk.core.refactoring.RefactoringChangeDescriptor;
import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.TextFileChange;
import org.eclipse.ltk.core.refactoring.participants.ResourceChangeChecker;
import org.eclipse.text.edits.InsertEdit;
import org.eclipse.text.edits.TextEdit;

/**
 * Extracts a method in a compilation unit based on a text selection range.
 */
public class ExtractMethodRefactoring extends Refactoring {

	//private static final String ATTRIBUTE_VISIBILITY= "visibility"; //$NON-NLS-1$
	private static final String ATTRIBUTE_DESTINATION= "destination"; //$NON-NLS-1$
	/*private static final String ATTRIBUTE_COMMENTS= "comments"; //$NON-NLS-1$
	private static final String ATTRIBUTE_REPLACE= "replace"; //$NON-NLS-1$
	private static final String ATTRIBUTE_EXCEPTIONS= "exceptions"; //$NON-NLS-1$*/

	private ISourceModule fCUnit;
	private String fSource;
	private Source fRoot;
	//private ImportRewrite fImportRewriter;
	private int fSelectionStart;
	private int fSelectionLength;
	/*private AST fAST;
	private ASTRewrite fRewriter;*/
	private ExtractMethodAnalyzer fAnalyzer;
	//private int fVisibility;
	private String fMethodName;
	//private boolean fThrowRuntimeExceptions;
	private List<ParameterInfo> fParameterInfos;
	private Set<String> fUsedNames;
	/*private boolean fGenerateScriptdoc;
	private boolean fReplaceDuplicates;
	private SnippetFinder.Match[] fDuplicates;*/
	private int fDestinationIndex= 0;
	private Node fDestination;
	private Node[] fDestinations;
	//private LinkedProposalModel fLinkedProposalModel;

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

	/*private static final String KEY_TYPE= "type"; //$NON-NLS-1$
	private static final String KEY_NAME= "name"; //$NON-NLS-1$

	private static class UsedNamesCollector extends ASTVisitor {
		private Set result= new HashSet();
		private Set fIgnore= new HashSet();
		public static Set perform(ASTNode[] nodes) {
			UsedNamesCollector collector= new UsedNamesCollector();
			for (int i= 0; i < nodes.length; i++) {
				nodes[i].accept(collector);
			}
			return collector.result;
		}
		public boolean visit(FieldAccess node) {
			Expression exp= node.getExpression();
			if (exp != null)
				fIgnore.add(node.getName());
			return true;
		}
		public void endVisit(FieldAccess node) {
			fIgnore.remove(node.getName());
		}
		public boolean visit(MethodInvocation node) {
			Expression exp= node.getExpression();
			if (exp != null)
				fIgnore.add(node.getName());
			return true;
		}
		public void endVisit(MethodInvocation node) {
			fIgnore.remove(node.getName());
		}
		public boolean visit(QualifiedName node) {
			fIgnore.add(node.getName());
			return true;
		}
		public void endVisit(QualifiedName node) {
			fIgnore.remove(node.getName());
		}
		public boolean visit(SimpleName node) {
			if (!fIgnore.contains(node))
				result.add(node.getIdentifier());
			return true;
		}
		public boolean visit(TypeDeclaration node) {
			return visitType(node);
		}
		public boolean visit(AnnotationTypeDeclaration node) {
			return visitType(node);
		}
		public boolean visit(EnumDeclaration node) {
			return visitType(node);
		}
		private boolean visitType(AbstractTypeDeclaration node) {
			result.add(node.getName().getIdentifier());
			// don't dive into type declaration since they open a new
			// context.
			return false;
		}
	}

	/**
	 * Creates a new extract method refactoring
	 * @param unit the compilation unit, or <code>null</code> if invoked by scripting
	 * @param selectionStart selection start
	 * @param selectionLength selection end
	 */
	public ExtractMethodRefactoring(ISourceModule unit, int selectionStart, int selectionLength) {
		fCUnit= unit;
		fRoot= null;
		fMethodName= "extracted"; //$NON-NLS-1$
		fSelectionStart= selectionStart;
		fSelectionLength= selectionLength;
		//fVisibility= -1;
	}

    /*public ExtractMethodRefactoring(ScriptRefactoringArguments arguments, RefactoringStatus status) {
   		this((ISourceModule) null, 0, 0);
   		RefactoringStatus initializeStatus= initialize(arguments);
   		status.merge(initializeStatus);
    }

	/**
	 * Creates a new extract method refactoring
	 * @param astRoot the AST root of an AST created from a compilation unit
	 * @param selectionStart start
	 * @param selectionLength length
	 *
	public ExtractMethodRefactoring(Source astRoot, int selectionStart, int selectionLength) {
		this((ISourceModule) astRoot.getTypeRoot(), selectionStart, selectionLength);
		fRoot= astRoot;
	}

	public void setLinkedProposalModel(LinkedProposalModel linkedProposalModel) {
		fLinkedProposalModel= linkedProposalModel;
	}*/

	 public String getName() {
	 	return RefactoringCoreMessages.ExtractMethodRefactoring_name;
	 }

	/**
	 * Checks if the refactoring can be activated. Activation typically means, if a
	 * corresponding menu entry can be added to the UI.
	 *
	 * @param pm a progress monitor to report progress during activation checking.
	 * @return the refactoring status describing the result of the activation check.
	 * @throws CoreException if checking fails
	 */
	public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException {
		RefactoringStatus result= new RefactoringStatus();
		pm.beginTask("", 100); //$NON-NLS-1$

		if (fSelectionStart < 0 || fSelectionLength == 0) {
			result.addFatalError(RefactoringCoreMessages.ExtractMethodRefactoring_no_set_of_statements);
			return result;
		}

		IFile[] changedFiles= ResourceUtil.getFiles(new ISourceModule[]{fCUnit});
		result.merge(RefactoringChecks.validateModifiesFiles(changedFiles, getValidationContext()));
		if (result.hasFatalError())
			return result;
		result.merge(ResourceChangeChecker.checkFilesToBeChanged(changedFiles, new SubProgressMonitor(pm, 1)));

		if (fRoot == null) {
			fRoot = (Source)ASTConverter.convert(JavaScriptParserUtil.parse(fCUnit));
		}
		//fImportRewriter= StubUtility.createImportRewrite(fRoot, true);

		//fAST= fRoot.getAST();
		fAnalyzer= new ExtractMethodAnalyzer(fCUnit, Selection.createFromStartLength(fSelectionStart, fSelectionLength));
		//fRoot.accept(fAnalyzer);

		result.merge(fAnalyzer.checkInitialConditions(fRoot));
		if (result.hasFatalError())
			return result;
		
		fSource = fCUnit.getSource();
		Node[] nodes = fAnalyzer.getSelectedNodes();
		boolean badSelection = false;
		for(int i=fSelectionStart;i<nodes[0].getBegin();i++)
			if (!Character.isWhitespace(fSource.charAt(i))) badSelection = true; 
		for(int i=nodes[nodes.length-1].getEnd();i<fSelectionStart+fSelectionLength;i++)
			if (!Character.isWhitespace(fSource.charAt(i))) badSelection = true;
		if (badSelection) {
			result.addFatalError(RefactoringCoreMessages.StatementAnalyzer_doesNotCover);
			return result;
		}
		/*if (fVisibility == -1) {
			setVisibility(Modifier.PRIVATE);
		}*/
		initializeParameterInfos();
		initializeUsedNames();
		//initializeDuplicates();
		initializeDestinations();
		return result;
	}

	/**
	 * Sets the method name to be used for the extracted method.
	 *
	 * @param name the new method name.
	 */
	public void setMethodName(String name) {
		fMethodName= name;
	}

	/**
	 * Returns the method name to be used for the extracted method.
	 * @return the method name to be used for the extracted method.
	 *
	public String getMethodName() {
		return fMethodName;
	}

	/**
	 * Sets the visibility of the new method.
	 *
	 * @param visibility the visibility of the new method. Valid values are
	 *  "public", "protected", "", and "private"
	 *
	public void setVisibility(int visibility) {
		fVisibility= visibility;
	}

	/**
	 * Returns the visibility of the new method.
	 *
	 * @return the visibility of the new method
	 *
	public int getVisibility() {
		return fVisibility;
	}

	/**
	 * Returns the parameter infos.
	 * @return a list of parameter infos.
	 */
	public List<ParameterInfo> getParameterInfos() {
		return fParameterInfos;
	}

	/**
	 * Sets whether the new method signature throws runtime exceptions.
	 *
	 * @param throwRuntimeExceptions flag indicating if the new method
	 * 	throws runtime exceptions
	 *
	public void setThrowRuntimeExceptions(boolean throwRuntimeExceptions) {
		fThrowRuntimeExceptions= throwRuntimeExceptions;
	}

	/**
	 * Checks if the new method name is a valid method name. This method doesn't
	 * check if a method with the same name already exists in the hierarchy. This
	 * check is done in <code>checkInput</code> since it is expensive.
	 * @return validation status
	 */
	public RefactoringStatus checkMethodName() {
		return Checks.validateIdentifier(fMethodName);
	}

	public Node[] getDestinations() {
		return fDestinations;
	}

	public void setDestination(int index) {
		fDestination= fDestinations[index];
		fDestinationIndex= index;
	}

	/**
	 * Checks if the parameter names are valid.
	 * @return validation status
	 */
	public RefactoringStatus checkParameterNames() {
		RefactoringStatus result= new RefactoringStatus();
		for (ParameterInfo parameter : fParameterInfos) {
			result.merge(Checks.validateIdentifier(parameter.getNewName()));
			for (ParameterInfo other : fParameterInfos) {
				if (parameter != other && other.getNewName().equals(parameter.getNewName())) {
					result.addError(Messages.format(
						RefactoringCoreMessages.ExtractMethodRefactoring_error_sameParameter,
						//BasicElementLabels.getScriptElementName(other.getNewName())
						other.getNewName()));
					return result;
				}
			}
			if (parameter.isRenamed() && fUsedNames.contains(parameter.getNewName())) {
				result.addError(Messages.format(
					RefactoringCoreMessages.ExtractMethodRefactoring_error_nameInUse,
					//BasicElementLabels.getScriptElementName(parameter.getNewName())
					parameter.getNewName()));
				return result;
			}
		}
		return result;
	}

	/**
	 * Checks if varargs are ordered correctly.
	 * @return validation status
	 *
	public RefactoringStatus checkVarargOrder() {
		for (Iterator iter= fParameterInfos.iterator(); iter.hasNext();) {
			ParameterInfo info= (ParameterInfo)iter.next();
			if (info.isOldVarargs() && iter.hasNext()) {
				return RefactoringStatus.createFatalErrorStatus(Messages.format(
					 RefactoringCoreMessages.ExtractMethodRefactoring_error_vararg_ordering,
					 BasicElementLabels.getScriptElementName(info.getOldName())));
			}
		}
		return new RefactoringStatus();
	}

	/**
	 * Returns the names already in use in the selected statements/expressions.
	 *
	 * @return names already in use.
	 *
	public Set getUsedNames() {
		return fUsedNames;
	}

	/* (non-Scriptdoc)
	 * Method declared in Refactoring
	 */
	public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreException {
		pm.beginTask(RefactoringCoreMessages.ExtractMethodRefactoring_checking_new_name, 1);
		pm.subTask(EMPTY);

		RefactoringStatus result= checkMethodName();
		result.merge(checkParameterNames());
		/*result.merge(checkVarargOrder());
		pm.worked(1);
		if (pm.isCanceled())
			throw new OperationCanceledException();

		Node node= fAnalyzer.getEnclosingNode();
		if (node != null) {
			fAnalyzer.checkInput(result, fMethodName);
			pm.worked(1);
		}*/
		pm.done();
		return result;
	}

	/* (non-Scriptdoc)
	 * Method declared in IRefactoring
	 */
	public Change createChange(IProgressMonitor pm) throws CoreException {
		if (fMethodName == null)
			return null;
		pm.beginTask("", 2); //$NON-NLS-1$
		try {
			ChangeRecorder cr = new ChangeRecorder(fRoot);
			Node[] nodes = fAnalyzer.getSelectedNodes();
			boolean isExpr = fAnalyzer.isExpressionSelected();
			// replace method parameter names
			Map<String,String> renamings = new HashMap<String,String>();
			for (ParameterInfo parameter : fParameterInfos)
				if (parameter.isRenamed())
					renamings.put(parameter.getOldName(),parameter.getNewName());
			for (Node node : nodes) {
				List<Identifier> oldNames = VariableLookup.findReferences(node, renamings.keySet());
				for (Identifier ref : oldNames) {
					ref.setName(renamings.get(ref.getName()));
				}
			}			
			// create call
			CallExpression invocation= DomFactory.eINSTANCE.createCallExpression();
			{
				VariableReference ref = DomFactory.eINSTANCE.createVariableReference();
				Identifier id = DomFactory.eINSTANCE.createIdentifier();
				id.setName(fMethodName);
				ref.setVariable(id);
				invocation.setApplicant(ref);
			}
			for (ParameterInfo parameter : fParameterInfos) {
				Identifier name = DomFactory.eINSTANCE.createIdentifier();
				name.setName(parameter.getOldName());
				VariableReference local = DomFactory.eINSTANCE.createVariableReference();
				local.setVariable(name);
				invocation.getArguments().add(local);
			}
			if (isExpr) {
				// replace with call
				EReference ref = nodes[0].eContainmentFeature();
				if (ref.isMany()) {
					EList<Expression> exprList = (EList<Expression>)nodes[0].eContainer().eGet(ref);
					exprList.set(exprList.lastIndexOf(nodes[0]), (Expression)invocation);
				} else {
					nodes[0].eContainer().eSet(ref, invocation);
				}
			} else {
				// create replacement
				Node call;
				int returnKind= fAnalyzer.getReturnKind();
				switch (returnKind) {
				case ExtractMethodAnalyzer.ACCESS_TO_LOCAL:
					VariableBinding binding= fAnalyzer.getReturnLocal();
					if (binding != null) {
						call = createDeclaration(binding, invocation);
					} else {
						BinaryExpression assignment= DomFactory.eINSTANCE.createBinaryExpression();
						assignment.setOperation(BinaryOperator.ASSIGN);
						VariableReference retVar = DomFactory.eINSTANCE.createVariableReference();
						Identifier id = DomFactory.eINSTANCE.createIdentifier();
						id.setName(fAnalyzer.getReturnValue().getName());
						retVar.setVariable(id);
						assignment.setLeft(retVar);
						assignment.setRight(invocation);
						call = assignment;
					}
					break;
				case ExtractMethodAnalyzer.RETURN_STATEMENT_VALUE:
					ReturnStatement rs=DomFactory.eINSTANCE.createReturnStatement();
					rs.setExpression(invocation);
					call = rs;
					break;
				default:
					call = invocation;
				}
				if (call instanceof Expression) {
					ExpressionStatement stmt = DomFactory.eINSTANCE.createExpressionStatement();
					stmt.setExpression((Expression)call);
					call = stmt;
				}
				List<Statement> callNodes= new ArrayList<Statement>(2);
				callNodes.add((Statement)call);
				if (returnKind == ExtractMethodAnalyzer.RETURN_STATEMENT_VOID && !fAnalyzer.isLastStatementSelected()) {
					callNodes.add(DomFactory.eINSTANCE.createReturnStatement());
				}
				for (VariableBinding local : fAnalyzer.getCallerLocals())
					callNodes.add(createDeclaration(local, null));
				// replace with call
				EReference ref = nodes[0].eContainmentFeature();
				if (ref.isMany()) {
					EList<Statement> list = (EList<Statement>)nodes[0].eContainer().eGet(ref);
					int index = list.lastIndexOf(nodes[0]);
					for(int i=nodes.length-1;i>=0;i--)
						list.remove(index+i);
					list.addAll(index, callNodes);
				} else if (callNodes.size() == 1) {
					nodes[0].eContainer().eSet(ref, callNodes.get(0));
				} else {
					BlockStatement block = DomFactory.eINSTANCE.createBlockStatement();
					block.getStatements().addAll(callNodes);
					nodes[0].eContainer().eSet(ref, block);
				}				
			}
			// create declaration
			FunctionExpression mm = createNewMethodDeclaration();
			List<Statement> statements = mm.getBody().getStatements();
			VariableBinding[] methodLocals= fAnalyzer.getMethodLocals();
			for (int i= 0; i < methodLocals.length; i++) {
				if (methodLocals[i] != null)
					statements.add(createDeclaration(methodLocals[i],null));
			}
			if (isExpr) {
				ReturnStatement rs = DomFactory.eINSTANCE.createReturnStatement();
				rs.setExpression((Expression)nodes[0]);
				statements.add(rs);
			} else {
				for(Node node : nodes) 
					statements.add((Statement)node);
				VariableBinding returnValue= fAnalyzer.getReturnValue();
				if (returnValue != null) {
					ReturnStatement rs = DomFactory.eINSTANCE.createReturnStatement();
					VariableReference ret = DomFactory.eINSTANCE.createVariableReference();
					Identifier rid = DomFactory.eINSTANCE.createIdentifier();
					String name = returnValue.getName();
					if (renamings.containsKey(name))
						name = renamings.get(name);
					rid.setName(name);
					ret.setVariable(rid);
					rs.setExpression(ret);
					statements.add(rs);
				}
			}
			// add declaration
			final ExpressionStatement stmt = DomFactory.eINSTANCE.createExpressionStatement();
			stmt.setExpression(mm);
			Node enclosing = fDestination;
			EReference ref = enclosing.eContainmentFeature();
			assert ref.isMany();
			EList<Statement> list = (EList<Statement>)enclosing.eContainer().eGet(ref);
			list.add(list.lastIndexOf(enclosing)+1,stmt);
			// TODO replace branches
			ChangeDescription cd = cr.endRecording();
			RewriteAnalyzer ra = new RewriteAnalyzer(cd, fSource) {
				@Override
				protected void addEdit(TextEdit edit, Node node) {
					if (node == stmt) {
						edit = new InsertEdit(edit.getOffset(),
								lineDelimiter+((InsertEdit)edit).getText());
					}
					super.addEdit(edit, node);
				}
			};
			SourceModuleChange result= new SourceModuleChange(RefactoringCoreMessages.ExtractMethodRefactoring_change_name, fCUnit);
			ra.rewrite(fRoot);
			result.setSaveMode(TextFileChange.KEEP_SAVE_STATE);
			result.setDescriptor(new RefactoringChangeDescriptor(getRefactoringDescriptor()));
			result.setEdit(ra.getEdit());
			cd.apply();
			return result;
		} finally {
			pm.done();
		}
	}

	/*private void replaceBranches(final SourceModuleChange result) {
		ASTNode[] selectedNodes= fAnalyzer.getSelectedNodes();
		for (int i= 0; i < selectedNodes.length; i++) {
			ASTNode astNode= selectedNodes[i];
			astNode.accept(new ASTVisitor() {
				private LinkedList fOpenLoopLabels= new LinkedList();

				private void registerLoopLabel(Statement node) {
					String identifier;
					if (node.getParent() instanceof LabeledStatement) {
						LabeledStatement labeledStatement= (LabeledStatement)node.getParent();
						identifier= labeledStatement.getLabel().getIdentifier();
					} else {
						identifier= null;
					}
					fOpenLoopLabels.add(identifier);
				}
				
				public boolean visit(ForStatement node) {
					registerLoopLabel(node);
					return super.visit(node);
				}

				public void endVisit(ForStatement node) {
					fOpenLoopLabels.removeLast();
				}

				public boolean visit(WhileStatement node) {
					registerLoopLabel(node);
					return super.visit(node);
				}

				public void endVisit(WhileStatement node) {
					fOpenLoopLabels.removeLast();
				}

				public boolean visit(EnhancedForStatement node) {
					registerLoopLabel(node);
					return super.visit(node);
				}

				public void endVisit(EnhancedForStatement node) {
					fOpenLoopLabels.removeLast();
				}

				public boolean visit(DoStatement node) {
					registerLoopLabel(node);
					return super.visit(node);
				}

				public void endVisit(DoStatement node) {
					fOpenLoopLabels.removeLast();
				}

				public void endVisit(ContinueStatement node) {
					final SimpleName label= node.getLabel();
					if (fOpenLoopLabels.isEmpty() || (label != null && !fOpenLoopLabels.contains(label.getIdentifier()))) {
						TextEditGroup description= new TextEditGroup(RefactoringCoreMessages.ExtractMethodRefactoring_replace_continue);
						result.addTextEditGroup(description);

						ReturnStatement rs= fAST.newReturnStatement();
						IVariableBinding returnValue= fAnalyzer.getReturnValue();
						if (returnValue != null) {
							rs.setExpression(fAST.newSimpleName(getName(returnValue)));
						}

						fRewriter.replace(node, rs, description);
					}
				}
			});
		}
	}*/

	private ExtractMethodDescriptor getRefactoringDescriptor() {
		final Map arguments= new HashMap();
		String project= null;
		IScriptProject ScriptProject= fCUnit.getScriptProject();
		if (ScriptProject != null)
			project= ScriptProject.getElementName();
		/*ITypeBinding type= null;
		if (fDestination instanceof AbstractTypeDeclaration) {
			final AbstractTypeDeclaration decl= (AbstractTypeDeclaration) fDestination;
			type= decl.resolveBinding();
		} else if (fDestination instanceof AnonymousClassDeclaration) {
			final AnonymousClassDeclaration decl= (AnonymousClassDeclaration) fDestination;
			type= decl.resolveBinding();
		}
		IMethodBinding method= null;
		final Node enclosing= fAnalyzer.getEnclosingNode();
		if (enclosing instanceof MethodDeclaration) {
			final MethodDeclaration node= (MethodDeclaration) enclosing;
			method= node.resolveBinding();
		}*/
		final int flags= RefactoringDescriptor.STRUCTURAL_CHANGE | ScriptRefactoringDescriptor.ARCHIVE_REFACTORABLE | ScriptRefactoringDescriptor.ARCHIVE_IMPORTABLE;
		final String description= Messages.format(RefactoringCoreMessages.ExtractMethodRefactoring_descriptor_description_short, fMethodName);
		//final String label= method != null ? BindingLabelProvider.getBindingLabel(method, ScriptElementLabels.ALL_FULLY_QUALIFIED) : '{' + ScriptElementLabels.ELLIPSIS_STRING + '}';
		//final String header= Messages.format(RefactoringCoreMessages.ExtractMethodRefactoring_descriptor_description, new String[] { BasicElementLabels.getScriptElementName(getSignature()), label, BindingLabelProvider.getBindingLabel(type, ScriptElementLabels.ALL_FULLY_QUALIFIED)});
		//final ScriptRefactoringDescriptorComment comment= new ScriptRefactoringDescriptorComment(project, this, header);
		//comment.addSetting(Messages.format(RefactoringCoreMessages.ExtractMethodRefactoring_name_pattern, BasicElementLabels.getScriptElementName(fMethodName)));
		//comment.addSetting(Messages.format(RefactoringCoreMessages.ExtractMethodRefactoring_destination_pattern, BindingLabelProvider.getBindingLabel(type, ScriptElementLabels.ALL_FULLY_QUALIFIED)));
		//String visibility= JdtFlags.getVisibilityString(fVisibility);
		//if ("".equals(visibility)) //$NON-NLS-1$
		//	visibility= RefactoringCoreMessages.ExtractMethodRefactoring_default_visibility;
		//comment.addSetting(Messages.format(RefactoringCoreMessages.ExtractMethodRefactoring_visibility_pattern, visibility));
		//if (fThrowRuntimeExceptions)
		//	comment.addSetting(RefactoringCoreMessages.ExtractMethodRefactoring_declare_thrown_exceptions);
		//if (fReplaceDuplicates)
		//	comment.addSetting(RefactoringCoreMessages.ExtractMethodRefactoring_replace_occurrences);
		//if (fGenerateScriptdoc)
		//	comment.addSetting(RefactoringCoreMessages.ExtractMethodRefactoring_generate_comment);
		final ExtractMethodDescriptor descriptor= new ExtractMethodDescriptor(project, description, ""/*comment.asString()*/, arguments, flags);
		arguments.put(ScriptRefactoringDescriptor.ATTRIBUTE_INPUT, ScriptRefactoringDescriptor.elementToHandle(project, fCUnit));
		arguments.put(ScriptRefactoringDescriptor.ATTRIBUTE_NAME, fMethodName);
		arguments.put(ScriptRefactoringDescriptor.ATTRIBUTE_SELECTION, new Integer(fSelectionStart).toString() + " " + new Integer(fSelectionLength).toString()); //$NON-NLS-1$
		//arguments.put(ATTRIBUTE_VISIBILITY, new Integer(fVisibility).toString());
		arguments.put(ATTRIBUTE_DESTINATION, new Integer(fDestinationIndex).toString());
		//arguments.put(ATTRIBUTE_EXCEPTIONS, Boolean.valueOf(fThrowRuntimeExceptions).toString());
		//arguments.put(ATTRIBUTE_COMMENTS, Boolean.valueOf(fGenerateScriptdoc).toString());
		//arguments.put(ATTRIBUTE_REPLACE, Boolean.valueOf(fReplaceDuplicates).toString());
		return descriptor;
	}

	/**
	 * Returns the signature of the new method.
	 *
	 * @return the signature of the extracted method
	 */
	public String getSignature() {
		return getSignature(fMethodName);
	}

	/**
	 * Returns the signature of the new method.
	 *
	 * @param methodName the method name used for the new method
	 * @return the signature of the extracted method
	 */
	public String getSignature(String methodName) {
		FunctionExpression methodDecl= createNewMethodDeclaration();
		String str = new Generator(null,"",0,"").generate(methodDecl).toString();
		return str.substring(0, str.indexOf('{')-1);
	}

	/*
	 * Returns the number of duplicate code snippets found.
	 *
	 * @return the number of duplicate code fragments
	 *
	public int getNumberOfDuplicates() {
		if (fDuplicates == null)
			return 0;
		int result=0;
		for (int i= 0; i < fDuplicates.length; i++) {
			if (!fDuplicates[i].isMethodBody())
				result++;
		}
		return result;
	}

	public boolean getReplaceDuplicates() {
		return fReplaceDuplicates;
	}

	public void setReplaceDuplicates(boolean replace) {
		fReplaceDuplicates= replace;
	}

	public void setGenerateScriptdoc(boolean generate) {
		fGenerateScriptdoc= generate;
	}

	public boolean getGenerateScriptdoc() {
		return fGenerateScriptdoc;
	}*/

	//---- Helper methods ------------------------------------------------------------------------

	private void initializeParameterInfos() {
		VariableBinding[] arguments= fAnalyzer.getArguments();
		fParameterInfos= new ArrayList<ParameterInfo>(arguments.length);
		for (int i= 0; i < arguments.length; i++) {
			String argument = arguments[i].getName();
			String type = arguments[i].getTypeName();
			if (type == null)
				type = "";
			fParameterInfos.add(new ParameterInfo(type, argument, i));
		}
	}

	private void initializeUsedNames() {
		// TODO might need more thinking
		fUsedNames = VariableLookup.getVisibleNames(fAnalyzer.getSelectedNodes()[0]);
		//fUsedNames= UsedNamesCollector.perform(fAnalyzer.getSelectedNodes());
		for (ParameterInfo parameter : fParameterInfos) {
			fUsedNames.remove(parameter.getOldName());
		}
	}

	/*private void initializeDuplicates() {
		ASTNode start= fAnalyzer.getEnclosingBodyDeclaration();
		while (!(start instanceof AbstractTypeDeclaration)) {
			start= start.getParent();
		}

		fDuplicates= SnippetFinder.perform(start, fAnalyzer.getSelectedNodes());
		fReplaceDuplicates= fDuplicates.length > 0 && ! fAnalyzer.isLiteralNodeSelected();
	}*/

	private void initializeDestinations() {
		List<Node> result= new ArrayList<Node>();
		Node node= fAnalyzer.getEnclosingNode();
		Node parent = node == null ? null : (Node)node.eContainer();
		Node grandparent = parent == null ? null : (Node)parent.eContainer();
		if (node instanceof Source) {
			Node cur = fAnalyzer.getSelectedNodes()[0];
			while (cur.eContainer() != node)
				cur = (Node)cur.eContainer();
			result.add(cur);
		} else {
			while (node != null) {
				if (parent instanceof Source) break;
				boolean stop = false;
				switch(grandparent.eClass().getClassifierID()) {
				case DomPackage.GETTER_ASSIGNMENT:
				case DomPackage.SETTER_ASSIGNMENT:
				case DomPackage.FUNCTION_EXPRESSION:
					stop = true;
				}
				if (stop) break;
				node = parent;
				parent = grandparent;
				grandparent = parent == null ? null : (Node)parent.eContainer();
			}
			if (node != null) result.add(node);
		}
		// TODO understand what we need here or we can just move manually after refactoring
		/*if (decl instanceof FunctionExpression) {
			//ITypeBinding binding= ASTNodes.getEnclosingType(current);
			Node next= getNextParent(current);
			while (next != null && binding != null && binding.isNested()) {
				result.add(next);
				current= next;
				binding= ASTNodes.getEnclosingType(current);
				next= getNextParent(next);
			}
		}*/
		fDestinations= (Node[])result.toArray(new Node[result.size()]);
		fDestination= fDestinations[fDestinationIndex];
	}

	private FunctionExpression createNewMethodDeclaration() {
		FunctionExpression result= DomFactory.eINSTANCE.createFunctionExpression();

		//int modifiers= fVisibility;
		/*Node enclosingBodyDeclaration= fAnalyzer.getEnclosingNode();
		while (enclosingBodyDeclaration != null && enclosingBodyDeclaration.eContainer() != fDestination) {
			enclosingBodyDeclaration= (Node)enclosingBodyDeclaration.eContainer();
		}
		if (enclosingBodyDeclaration instanceof BodyDeclaration) { // should always be the case
			int enclosingModifiers= ((BodyDeclaration)enclosingBodyDeclaration).getModifiers();
			boolean shouldBeStatic= Modifier.isStatic(enclosingModifiers) || fAnalyzer.getForceStatic();
			if (shouldBeStatic) {
				modifiers|= Modifier.STATIC;
			}
		}

		ITypeBinding[] typeVariables= computeLocalTypeVariables();
		List typeParameters= result.typeParameters();
		for (int i= 0; i < typeVariables.length; i++) {
			TypeParameter parameter= fAST.newTypeParameter();
			parameter.setName(fAST.newSimpleName(typeVariables[i].getName()));
			typeParameters.add(parameter);
		}

		result.modifiers().addAll(ASTNodeFactory.newModifiers(fAST, modifiers));
		result.setReturnType2((Type)ASTNode.copySubtree(fAST, fAnalyzer.getReturnType()));*/
		if (fAnalyzer.getReturnTypeName() != null) {
//			Type type = DomFactory.eINSTANCE.createType();
//			type.setName(fAnalyzer.getReturnTypeName());
//			result.setReturnType(type);
		}
		Identifier id = DomFactory.eINSTANCE.createIdentifier();
		id.setName(fMethodName);
		result.setIdentifier(id);

		List<Parameter> parameters= result.getParameters();
		for (int i= 0; i < fParameterInfos.size(); i++) {
			ParameterInfo info= (ParameterInfo)fParameterInfos.get(i);
			Parameter parameter= DomFactory.eINSTANCE.createParameter();
			Identifier prmName = DomFactory.eINSTANCE.createIdentifier();
			prmName.setName(info.getNewName());
			parameter.setName(prmName);
			if (!"".equals(info.getNewTypeName())) { //$NON-NLS-1
//				Type type = DomFactory.eINSTANCE.createType();
//				type.setName(info.getNewTypeName());
//				parameter.setType(type);
			}
			parameters.add(parameter);
		}

		/*List exceptions= result.thrownExceptions();
		ITypeBinding[] exceptionTypes= fAnalyzer.getExceptions(fThrowRuntimeExceptions);
		ImportRewriteContext context= new ContextSensitiveImportRewriteContext(enclosingBodyDeclaration, fImportRewriter);
		for (int i= 0; i < exceptionTypes.length; i++) {
			ITypeBinding exceptionType= exceptionTypes[i];
			exceptions.add(ASTNodeFactory.newName(fAST, fImportRewriter.addImport(exceptionType, context)));
		}*/
		result.setBody(DomFactory.eINSTANCE.createBlockStatement());
		return result;
	}

	/*private ITypeBinding[] computeLocalTypeVariables() {
		List result= new ArrayList(Arrays.asList(fAnalyzer.getTypeVariables()));
		for (int i= 0; i < fParameterInfos.size(); i++) {
			ParameterInfo info= (ParameterInfo)fParameterInfos.get(i);
			processVariable(result, info.getOldBinding());
		}
		IVariableBinding[] methodLocals= fAnalyzer.getMethodLocals();
		for (int i= 0; i < methodLocals.length; i++) {
			processVariable(result, methodLocals[i]);
		}
		return (ITypeBinding[])result.toArray(new ITypeBinding[result.size()]);
	}

	private void processVariable(List result, IVariableBinding variable) {
		if (variable == null)
			return;
		ITypeBinding binding= variable.getType();
		if (binding != null && binding.isParameterizedType()) {
			ITypeBinding[] typeArgs= binding.getTypeArguments();
			for (int args= 0; args < typeArgs.length; args++) {
				ITypeBinding arg= typeArgs[args];
				if (arg.isTypeVariable() && !result.contains(arg)) {
					ASTNode decl= fRoot.findDeclaringNode(arg);
					if (decl != null && decl.getParent() instanceof MethodDeclaration) {
						result.add(arg);
					}
				}
			}
		}
	}*/

	/*private String getName(IVariableBinding binding) {
		for (Iterator iter= fParameterInfos.iterator(); iter.hasNext();) {
			ParameterInfo info= (ParameterInfo)iter.next();
			if (Bindings.equals(binding, info.getOldBinding())) {
				return info.getNewName();
			}
		}
		return binding.getName();
	}

	private VariableDeclaration getVariableDeclaration(ParameterInfo parameter) {
		return ASTNodes.findVariableDeclaration(parameter.getOldBinding(), fAnalyzer.getEnclosingBodyDeclaration());
	}*/

	private VariableStatement createDeclaration(VariableBinding name, Expression initializer) {
		Identifier id = DomFactory.eINSTANCE.createIdentifier();
		id.setName(name.getName());
		VariableDeclaration decl = DomFactory.eINSTANCE.createVariableDeclaration();
		decl.setIdentifier(id);
		if (name.getTypeName() != null) {
//			Type type = DomFactory.eINSTANCE.createType();
//			type.setName(name.getTypeName());
		}
		if (initializer != null)
			decl.setInitializer(initializer);
		VariableStatement result = DomFactory.eINSTANCE.createVariableStatement();
		result.getDeclarations().add(decl);
		return result;
	}

	/*public ISourceModule getSource() {
		return fCUnit;
	}

	private RefactoringStatus initialize(ScriptRefactoringArguments arguments) {
		final String selection= arguments.getAttribute(ScriptRefactoringDescriptorUtil.ATTRIBUTE_SELECTION);
		if (selection == null)
			return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ScriptRefactoringDescriptorUtil.ATTRIBUTE_SELECTION));

		int offset= -1;
		int length= -1;
		final StringTokenizer tokenizer= new StringTokenizer(selection);
		if (tokenizer.hasMoreTokens())
			offset= Integer.valueOf(tokenizer.nextToken()).intValue();
		if (tokenizer.hasMoreTokens())
			length= Integer.valueOf(tokenizer.nextToken()).intValue();
		if (offset < 0 || length < 0)
			return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_illegal_argument, new Object[] { selection, ScriptRefactoringDescriptorUtil.ATTRIBUTE_SELECTION}));

		fSelectionStart= offset;
		fSelectionLength= length;

		final String handle= arguments.getAttribute(ScriptRefactoringDescriptorUtil.ATTRIBUTE_INPUT);
		if (handle == null)
			return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ScriptRefactoringDescriptorUtil.ATTRIBUTE_INPUT));

		IScriptElement element= ScriptRefactoringDescriptorUtil.handleToElement(arguments.getProject(), handle, false);
		if (element == null || !element.exists() || element.getElementType() != IScriptElement.COMPILATION_UNIT)
			return ScriptRefactoringDescriptorUtil.createInputFatalStatus(element, getName(), IScriptRefactorings.EXTRACT_METHOD);

		fCUnit= (ISourceModule) element;
		final String visibility= arguments.getAttribute(ATTRIBUTE_VISIBILITY);
		if (visibility != null && visibility.length() != 0) {
			int flag= 0;
			try {
				flag= Integer.parseInt(visibility);
			} catch (NumberFormatException exception) {
				return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_VISIBILITY));
			}
			fVisibility= flag;
		}
		final String name= arguments.getAttribute(ScriptRefactoringDescriptorUtil.ATTRIBUTE_NAME);
		if (name == null || name.length() == 0)
			return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ScriptRefactoringDescriptorUtil.ATTRIBUTE_NAME));

		fMethodName= name;

		final String destination= arguments.getAttribute(ATTRIBUTE_DESTINATION);
		if (destination != null && destination.length() == 0) {
			int index= 0;
			try {
				index= Integer.parseInt(destination);
			} catch (NumberFormatException exception) {
				return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_DESTINATION));
			}
			fDestinationIndex= index;
		}
		final String replace= arguments.getAttribute(ATTRIBUTE_REPLACE);
		if (replace == null)
			return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_REPLACE));

		fReplaceDuplicates= Boolean.valueOf(replace).booleanValue();

		final String comments= arguments.getAttribute(ATTRIBUTE_COMMENTS);
		if (comments == null)
			return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_COMMENTS));

		fGenerateScriptdoc= Boolean.valueOf(comments).booleanValue();

		final String exceptions= arguments.getAttribute(ATTRIBUTE_EXCEPTIONS);
		if (exceptions == null)
			return RefactoringStatus.createFatalErrorStatus(Messages.format(RefactoringCoreMessages.InitializableRefactoring_argument_not_exist, ATTRIBUTE_EXCEPTIONS));

		fThrowRuntimeExceptions= Boolean.valueOf(exceptions).booleanValue();

		return new RefactoringStatus();
	}*/
}
