/*******************************************************************************
 * Copyright (c) 2000, 2021 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     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] Name ambiguous return value in error message - https://bugs.eclipse.org/bugs/show_bug.cgi?id=50607
 *******************************************************************************/
package org.eclipse.jdt.internal.corext.refactoring.code;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import com.ibm.icu.text.MessageFormat;

import org.eclipse.core.runtime.CoreException;

import org.eclipse.jface.text.IRegion;

import org.eclipse.ltk.core.refactoring.RefactoringStatus;

import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.compiler.ITerminalSymbols;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.Annotation;
import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
import org.eclipse.jdt.core.dom.Assignment;
import org.eclipse.jdt.core.dom.Block;
import org.eclipse.jdt.core.dom.BodyDeclaration;
import org.eclipse.jdt.core.dom.BreakStatement;
import org.eclipse.jdt.core.dom.ClassInstanceCreation;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.ConstructorInvocation;
import org.eclipse.jdt.core.dom.ContinueStatement;
import org.eclipse.jdt.core.dom.DoStatement;
import org.eclipse.jdt.core.dom.EnhancedForStatement;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.FieldAccess;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.ForStatement;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.Initializer;
import org.eclipse.jdt.core.dom.LabeledStatement;
import org.eclipse.jdt.core.dom.LambdaExpression;
import org.eclipse.jdt.core.dom.Message;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.NodeFinder;
import org.eclipse.jdt.core.dom.PrimitiveType;
import org.eclipse.jdt.core.dom.QualifiedName;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.Statement;
import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor;
import org.eclipse.jdt.core.dom.SuperConstructorInvocation;
import org.eclipse.jdt.core.dom.SwitchCase;
import org.eclipse.jdt.core.dom.SwitchStatement;
import org.eclipse.jdt.core.dom.ThisExpression;
import org.eclipse.jdt.core.dom.TryStatement;
import org.eclipse.jdt.core.dom.Type;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.VariableDeclaration;
import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
import org.eclipse.jdt.core.dom.WhileStatement;
import org.eclipse.jdt.core.dom.YieldStatement;
import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;
import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.ImportRewriteContext;
import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.TypeLocation;

import org.eclipse.jdt.internal.core.manipulation.dom.ASTResolving;
import org.eclipse.jdt.internal.core.manipulation.util.BasicElementLabels;
import org.eclipse.jdt.internal.corext.codemanipulation.ContextSensitiveImportRewriteContext;
import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory;
import org.eclipse.jdt.internal.corext.dom.ASTNodes;
import org.eclipse.jdt.internal.corext.dom.Bindings;
import org.eclipse.jdt.internal.corext.dom.LocalVariableIndex;
import org.eclipse.jdt.internal.corext.dom.Selection;
import org.eclipse.jdt.internal.corext.dom.TokenScanner;
import org.eclipse.jdt.internal.corext.refactoring.Checks;
import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
import org.eclipse.jdt.internal.corext.refactoring.code.flow.FlowContext;
import org.eclipse.jdt.internal.corext.refactoring.code.flow.FlowInfo;
import org.eclipse.jdt.internal.corext.refactoring.code.flow.InOutFlowAnalyzer;
import org.eclipse.jdt.internal.corext.refactoring.code.flow.InputFlowAnalyzer;
import org.eclipse.jdt.internal.corext.refactoring.util.CodeAnalyzer;
import org.eclipse.jdt.internal.corext.refactoring.util.JavaStatusContext;
import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
import org.eclipse.jdt.internal.corext.util.Messages;

import org.eclipse.jdt.ui.JavaElementLabels;

import org.eclipse.jdt.internal.ui.viewsupport.BindingLabelProvider;

/* package */ class ExtractMethodAnalyzer extends CodeAnalyzer {

	public static final int ERROR=					-2;
	public static final int UNDEFINED=				-1;
	public static final int NO=						0;
	public static final int EXPRESSION=				1;
	public static final int ACCESS_TO_LOCAL=		2;
	public static final int RETURN_STATEMENT_VOID=	3;
	public static final int RETURN_STATEMENT_VALUE=	4;
	public static final int MULTIPLE=				5;

	/** This is either a method declaration or an initializer */
	private BodyDeclaration fEnclosingBodyDeclaration;
	private IMethodBinding fEnclosingMethodBinding;
	private int fMaxVariableId;

	private int fReturnKind;
	private Type fReturnType;
	private ITypeBinding fReturnTypeBinding;

	private FlowInfo fInputFlowInfo;
	private FlowContext fInputFlowContext;

	private IVariableBinding[] fArguments;
	private IVariableBinding[] fMethodLocals;
	private ITypeBinding[] fTypeVariables;

	private IVariableBinding fReturnValue;
	private IVariableBinding[] fCallerLocals;
	private IVariableBinding fReturnLocal;

	private ITypeBinding[] fAllExceptions;
	private ITypeBinding fExpressionBinding;

	private boolean fForceStatic;
	private boolean fIsLastStatementSelected;
	private SimpleName fEnclosingLoopLabel;

	public ExtractMethodAnalyzer(ICompilationUnit unit, Selection selection) throws CoreException {
		super(unit, selection, false);
	}

	public BodyDeclaration getEnclosingBodyDeclaration() {
		return fEnclosingBodyDeclaration;
	}

	public int getReturnKind() {
		return fReturnKind;
	}

	public boolean extractsExpression() {
		return fReturnKind == EXPRESSION;
	}

	public Type getReturnType() {
		return fReturnType;
	}

	public ITypeBinding getReturnTypeBinding() {
		return fReturnTypeBinding;
	}

	public boolean generateImport() {
		switch (fReturnKind) {
			case EXPRESSION:
				return true;
			default:
				return false;
		}
	}

	public IVariableBinding[] getArguments() {
		return fArguments;
	}

	public IVariableBinding[] getMethodLocals() {
		return fMethodLocals;
	}

	public IVariableBinding getReturnValue() {
		return fReturnValue;
	}

	public IVariableBinding[] getCallerLocals() {
		return fCallerLocals;
	}

	public IVariableBinding getReturnLocal() {
		return fReturnLocal;
	}

	public ITypeBinding getExpressionBinding() {
		return fExpressionBinding;
	}

	public boolean getForceStatic() {
		return fForceStatic;
	}

	public ITypeBinding[] getTypeVariables() {
		return fTypeVariables;
	}

	//---- Activation checking ---------------------------------------------------------------------------

	boolean isValidDestination(ASTNode node) {
		boolean isInterface= node instanceof TypeDeclaration && ((TypeDeclaration) node).isInterface();
		return !(node instanceof AnnotationTypeDeclaration) &&
				(!isInterface || JavaModelUtil.is1d8OrHigher(fCUnit.getJavaProject()));
	}

	public RefactoringStatus checkInitialConditions(ImportRewrite rewriter) {
		RefactoringStatus result= getStatus();
		checkExpression(result);
		if (result.hasFatalError())
			return result;

		List<ASTNode> validDestinations= new ArrayList<>();
		ASTNode destination= ASTResolving.findParentType(fEnclosingBodyDeclaration.getParent());
		while (destination != null) {
			if (isValidDestination(destination)) {
				validDestinations.add(destination);
			}
			destination= ASTResolving.findParentType(destination.getParent());
		}
		if (validDestinations.isEmpty()) {
			result.addFatalError(RefactoringCoreMessages.ExtractMethodAnalyzer_no_valid_destination_type);
			return result;
		}

		fReturnKind= UNDEFINED;
		fMaxVariableId= LocalVariableIndex.perform(fEnclosingBodyDeclaration);
		if (analyzeSelection(result).hasFatalError())
			return result;

		int returns= fReturnKind == NO ? 0 : 1;
		if (fReturnValue != null) {
			fReturnKind= ACCESS_TO_LOCAL;
			returns++;
		}
		if (isExpressionSelected()) {
			fReturnKind= EXPRESSION;
			returns++;
		}

		if (returns > 1) {
			result.addFatalError(RefactoringCoreMessages.ExtractMethodAnalyzer_ambiguous_return_value, JavaStatusContext.create(fCUnit, getSelection()));
			fReturnKind= MULTIPLE;
			return result;
		}
		initReturnType(rewriter);
		return result;
	}

	private void checkExpression(RefactoringStatus status) {
		ASTNode[] nodes= getSelectedNodes();
		if (nodes != null && nodes.length == 1) {
			ASTNode node= nodes[0];
			if (node instanceof Type) {
				status.addFatalError(RefactoringCoreMessages.ExtractMethodAnalyzer_cannot_extract_type_reference, JavaStatusContext.create(fCUnit, node));
			} else if (node.getLocationInParent() == SwitchCase.EXPRESSION_PROPERTY || node.getLocationInParent() == SwitchCase.EXPRESSIONS2_PROPERTY) {
				status.addFatalError(RefactoringCoreMessages.ExtractMethodAnalyzer_cannot_extract_switch_case, JavaStatusContext.create(fCUnit, node));
			} else if (node instanceof Annotation || ASTNodes.getParent(node, Annotation.class) != null) {
				status.addFatalError(RefactoringCoreMessages.ExtractMethodAnalyzer_cannot_extract_from_annotation, JavaStatusContext.create(fCUnit, node));
			}
		}
	}

	private void initReturnType(ImportRewrite rewriter) {
		AST ast= fEnclosingBodyDeclaration.getAST();
		fReturnType= null;
		fReturnTypeBinding= null;
		switch (fReturnKind) {
			case ACCESS_TO_LOCAL:
				VariableDeclaration declaration= ASTNodes.findVariableDeclaration(fReturnValue, fEnclosingBodyDeclaration);
				fReturnType= ASTNodeFactory.newNonVarType(ast, declaration, rewriter, new ContextSensitiveImportRewriteContext(declaration, rewriter));
				if (declaration.resolveBinding() != null) {
					fReturnTypeBinding= declaration.resolveBinding().getType();
				}
				break;
			case EXPRESSION:
				Expression expression= (Expression)getFirstSelectedNode();
				if (expression.getNodeType() == ASTNode.CLASS_INSTANCE_CREATION) {
					fExpressionBinding= ((ClassInstanceCreation)expression).getType().resolveBinding();
				} else {
					fExpressionBinding= expression.resolveTypeBinding();
				}
				if (fExpressionBinding != null) {
					if (fExpressionBinding.isNullType()) {
						getStatus().addFatalError(RefactoringCoreMessages.ExtractMethodAnalyzer_cannot_extract_null_type, JavaStatusContext.create(fCUnit, expression));
					} else {
						ITypeBinding normalizedBinding= Bindings.normalizeForDeclarationUse(fExpressionBinding, ast);
						if (normalizedBinding != null) {
							ImportRewriteContext context= new ContextSensitiveImportRewriteContext(fEnclosingBodyDeclaration, rewriter);
							fReturnType= rewriter.addImport(normalizedBinding, ast, context, TypeLocation.RETURN_TYPE);
							fReturnTypeBinding= normalizedBinding;
						}
					}
				} else {
					fReturnType= ast.newPrimitiveType(PrimitiveType.VOID);
					fReturnTypeBinding= ast.resolveWellKnownType("void"); //$NON-NLS-1$
					getStatus().addError(RefactoringCoreMessages.ExtractMethodAnalyzer_cannot_determine_return_type, JavaStatusContext.create(fCUnit, expression));
				}
				break;
			case RETURN_STATEMENT_VALUE:
				LambdaExpression enclosingLambdaExpr= ASTResolving.findEnclosingLambdaExpression(getFirstSelectedNode());
				if (enclosingLambdaExpr != null) {
					fReturnType= ASTNodeFactory.newReturnType(enclosingLambdaExpr, ast, rewriter, null);
					IMethodBinding methodBinding= enclosingLambdaExpr.resolveMethodBinding();
					fReturnTypeBinding= methodBinding != null ? methodBinding.getReturnType() : null;
				} else if (fEnclosingBodyDeclaration.getNodeType() == ASTNode.METHOD_DECLARATION) {
					fReturnType= ((MethodDeclaration) fEnclosingBodyDeclaration).getReturnType2();
					fReturnTypeBinding= fReturnType != null ? fReturnType.resolveBinding() : null;
				}
				break;
			default:
				fReturnType= ast.newPrimitiveType(PrimitiveType.VOID);
				fReturnTypeBinding= ast.resolveWellKnownType("void"); //$NON-NLS-1$
		}
		if (fReturnType == null) {
			fReturnType= ast.newPrimitiveType(PrimitiveType.VOID);
			fReturnTypeBinding= ast.resolveWellKnownType("void"); //$NON-NLS-1$
		}
	}

	//	 !!! -- +/- same as in ExtractTempRefactoring
	public boolean isLiteralNodeSelected() {
		ASTNode[] nodes= getSelectedNodes();
		if (nodes.length != 1)
			return false;
		ASTNode node= nodes[0];
		switch (node.getNodeType()) {
			case ASTNode.BOOLEAN_LITERAL :
			case ASTNode.CHARACTER_LITERAL :
			case ASTNode.NULL_LITERAL :
			case ASTNode.NUMBER_LITERAL :
				return true;

			default :
				return false;
		}
	}

	//---- Input checking -----------------------------------------------------------------------------------

	public void checkInput(RefactoringStatus status, String methodName, ASTNode destination) {
		ITypeBinding[] arguments= getArgumentTypes();
		ITypeBinding type= ASTNodes.getEnclosingType(destination);
		status.merge(Checks.checkMethodInType(type, methodName, arguments));
		ITypeBinding superClass= type.getSuperclass();
		if (superClass != null) {
			status.merge(Checks.checkMethodInHierarchy(superClass, methodName, null, arguments));
		}
		for (ITypeBinding superInterface : type.getInterfaces()) {
			status.merge(Checks.checkMethodInHierarchy(superInterface, methodName, null, arguments));
		}
	}

	private ITypeBinding[] getArgumentTypes() {
		ITypeBinding[] result= new ITypeBinding[fArguments.length];
		for (int i= 0; i < fArguments.length; i++) {
			result[i]= fArguments[i].getType();
		}
		return result;
	}

	private RefactoringStatus analyzeSelection(RefactoringStatus status) {
		fInputFlowContext= new FlowContext(0, fMaxVariableId + 1);
		fInputFlowContext.setConsiderAccessMode(true);
		fInputFlowContext.setComputeMode(FlowContext.ARGUMENTS);

		InOutFlowAnalyzer flowAnalyzer= new InOutFlowAnalyzer(fInputFlowContext);
		fInputFlowInfo= flowAnalyzer.perform(getSelectedNodes());

		if (fInputFlowInfo.branches()) {
			String canHandleBranchesProblem= canHandleBranches();
			if (canHandleBranchesProblem != null) {
				status.addFatalError(canHandleBranchesProblem, JavaStatusContext.create(fCUnit, getSelection()));
				fReturnKind= ERROR;
				return status;
			}
		}
		if (fInputFlowInfo.isValueReturn()) {
			fReturnKind= RETURN_STATEMENT_VALUE;
		} else  if (fInputFlowInfo.isVoidReturn() || (fInputFlowInfo.isPartialReturn() && isVoidMethod() && isLastStatementSelected())) {
			fReturnKind= RETURN_STATEMENT_VOID;
		} else if (fInputFlowInfo.isNoReturn() || fInputFlowInfo.isThrow() || fInputFlowInfo.isUndefined()) {
			fReturnKind= NO;
		}

		if (fReturnKind == UNDEFINED) {
			status.addError(RefactoringCoreMessages.FlowAnalyzer_execution_flow, JavaStatusContext.create(fCUnit, getSelection()));
			fReturnKind= NO;
		}
		computeInput();
		computeExceptions();
		computeOutput(status);
		if (status.hasFatalError())
			return status;

		adjustArgumentsAndMethodLocals();
		compressArrays();
		return status;
	}

	private String canHandleBranches() {
		if (fReturnValue != null)
			return RefactoringCoreMessages.ExtractMethodAnalyzer_branch_mismatch;

		ASTNode[] selectedNodes= getSelectedNodes();
		final ASTNode lastSelectedNode= selectedNodes[selectedNodes.length - 1];
		Statement body= getParentLoopBody(lastSelectedNode.getParent());
		if (!(body instanceof Block))
			return RefactoringCoreMessages.ExtractMethodAnalyzer_branch_mismatch;

		if (body != lastSelectedNode) {
			Block block= (Block)body;
			List<Statement> statements= block.statements();
			ASTNode lastStatementInLoop= statements.get(statements.size() - 1);
			if (lastSelectedNode != lastStatementInLoop)
				return RefactoringCoreMessages.ExtractMethodAnalyzer_branch_mismatch;
		}

		final String continueMatchesLoopProblem[]= { null };
		for (ASTNode astNode : selectedNodes) {
			astNode.accept(new ASTVisitor() {
				ArrayList<String> fLocalLoopLabels= new ArrayList<>();
				ArrayList<Statement> fBreakTargets= new ArrayList<>();

				@Override
				public boolean visit(BreakStatement node) {
					SimpleName label= node.getLabel();
					if (label != null && !fLocalLoopLabels.contains(label.getIdentifier())) {
						continueMatchesLoopProblem[0]= Messages.format(
							RefactoringCoreMessages.ExtractMethodAnalyzer_branch_break_mismatch,
							new Object[] { ("break " + label.getIdentifier()) }); //$NON-NLS-1$
					} else if (label == null) {
						ASTNode parentStatement= ASTNodes.getFirstAncestorOrNull(node, WhileStatement.class, ForStatement.class,
								DoStatement.class, SwitchStatement.class, EnhancedForStatement.class);
						if (parentStatement != null && !fBreakTargets.contains(parentStatement)) {
							continueMatchesLoopProblem[0]= RefactoringCoreMessages.ExtractMethodAnalyzer_break_parent_missing;
						}
					}
					return false;
				}

				@Override
				public boolean visit(LabeledStatement node) {
					SimpleName label= node.getLabel();
					if (label != null)
						fLocalLoopLabels.add(label.getIdentifier());
					return true;
				}

				@Override
				public void endVisit(ForStatement node) {
					fBreakTargets.add(node);
				}

				@Override
				public void endVisit(EnhancedForStatement node) {
					fBreakTargets.add(node);
				}

				@Override
				public void endVisit(DoStatement node) {
					fBreakTargets.add(node);
				}

				@Override
				public void endVisit(SwitchStatement node) {
					fBreakTargets.add(node);
				}

				@Override
				public void endVisit(WhileStatement node) {
					fBreakTargets.add(node);
				}

				@Override
				public void endVisit(ContinueStatement node) {
					SimpleName label= node.getLabel();
					if (label != null && !fLocalLoopLabels.contains(label.getIdentifier())) {
						if (fEnclosingLoopLabel == null || ! label.getIdentifier().equals(fEnclosingLoopLabel.getIdentifier())) {
							continueMatchesLoopProblem[0]= Messages.format(
								RefactoringCoreMessages.ExtractMethodAnalyzer_branch_continue_mismatch,
								new Object[] { "continue " + label.getIdentifier() }); //$NON-NLS-1$
						}
					}
				}
			});
		}
		return continueMatchesLoopProblem[0];
	}

	private Statement getParentLoopBody(ASTNode node) {
		Statement stmt= null;
		ASTNode start= node;
		while (start != null
				&& !(start instanceof ForStatement)
				&& !(start instanceof DoStatement)
				&& !(start instanceof WhileStatement)
				&& !(start instanceof EnhancedForStatement)
				&& !(start instanceof SwitchStatement)) {
			start= start.getParent();
		}
		if (start instanceof ForStatement) {
			stmt= ((ForStatement)start).getBody();
		} else if (start instanceof DoStatement) {
			stmt= ((DoStatement)start).getBody();
		} else if (start instanceof WhileStatement) {
			stmt= ((WhileStatement)start).getBody();
		} else if (start instanceof EnhancedForStatement) {
			stmt= ((EnhancedForStatement)start).getBody();
		}
		if (start != null && start.getParent() instanceof LabeledStatement) {
			LabeledStatement labeledStatement= (LabeledStatement)start.getParent();
			fEnclosingLoopLabel= labeledStatement.getLabel();
		}
		return stmt;
	}

	private boolean isVoidMethod() {
		ITypeBinding binding= null;
		LambdaExpression enclosingLambdaExpr= ASTResolving.findEnclosingLambdaExpression(getFirstSelectedNode());
		if (enclosingLambdaExpr != null) {
			IMethodBinding methodBinding= enclosingLambdaExpr.resolveMethodBinding();
			if (methodBinding != null) {
				binding= methodBinding.getReturnType();
			}
		} else {
			// if we have an initializer
			if (fEnclosingMethodBinding == null)
				return true;
			binding= fEnclosingMethodBinding.getReturnType();
		}
		if (fEnclosingBodyDeclaration.getAST().resolveWellKnownType("void").equals(binding)) //$NON-NLS-1$
			return true;
		return false;
	}

	public boolean isLastStatementSelected() {
		return fIsLastStatementSelected;
	}

	private void computeLastStatementSelected() {
		ASTNode[] nodes= getSelectedNodes();
		if (nodes.length == 0) {
			fIsLastStatementSelected= false;
		} else {
			Block body= null;
			LambdaExpression enclosingLambdaExpr= ASTResolving.findEnclosingLambdaExpression(getFirstSelectedNode());
			if (enclosingLambdaExpr != null) {
				ASTNode lambdaBody= enclosingLambdaExpr.getBody();
				if (lambdaBody instanceof Block) {
					body= (Block) lambdaBody;
				} else {
					fIsLastStatementSelected= true;
					return;
				}
			} else {
				if (fEnclosingBodyDeclaration instanceof MethodDeclaration) {
					body= ((MethodDeclaration) fEnclosingBodyDeclaration).getBody();
				} else if (fEnclosingBodyDeclaration instanceof Initializer) {
					body= ((Initializer) fEnclosingBodyDeclaration).getBody();
				}
			}
			if (body != null) {
				List<Statement> statements= body.statements();
				if (statements.size() > 0) {
					fIsLastStatementSelected= nodes[nodes.length - 1] == statements.get(statements.size() - 1);
				} else {
					fIsLastStatementSelected= true;
				}
			}
		}
	}

	private void computeInput() {
		int argumentMode= FlowInfo.READ | FlowInfo.READ_POTENTIAL | FlowInfo.WRITE_POTENTIAL | FlowInfo.UNKNOWN;
		fArguments= removeSelectedDeclarations(fInputFlowInfo.get(fInputFlowContext, argumentMode));
		fMethodLocals= removeSelectedDeclarations(fInputFlowInfo.get(fInputFlowContext, FlowInfo.WRITE | FlowInfo.WRITE_POTENTIAL));
		fTypeVariables= computeTypeVariables(fInputFlowInfo.getTypeVariables());
	}

	private IVariableBinding[] removeSelectedDeclarations(IVariableBinding[] bindings) {
		List<IVariableBinding> result= new ArrayList<>(bindings.length);
		Selection selection= getSelection();
		for (IVariableBinding binding : bindings) {
			ASTNode decl= ((CompilationUnit)fEnclosingBodyDeclaration.getRoot()).findDeclaringNode(binding);
			if (!selection.covers(decl)) {
				result.add(binding);
			}
		}
		return result.toArray(new IVariableBinding[result.size()]);
	}

	private ITypeBinding[] computeTypeVariables(ITypeBinding[] bindings) {
		Selection selection= getSelection();
		Set<ITypeBinding> result= new HashSet<>();
		// first remove all type variables that come from outside of the method
		// or are covered by the selection
		CompilationUnit compilationUnit= (CompilationUnit)fEnclosingBodyDeclaration.getRoot();
		for (ITypeBinding binding : bindings) {
			ASTNode decl= compilationUnit.findDeclaringNode(binding);
			if (decl == null || (!selection.covers(decl) && decl.getParent() instanceof MethodDeclaration)) {
				result.add(binding);
			}
		}
		// all all type variables which are needed since a local variable uses it
		for (IVariableBinding arg : fArguments) {
			ITypeBinding type= arg.getType();
			if (type != null && type.isTypeVariable()) {
				ASTNode decl= compilationUnit.findDeclaringNode(type);
				if (decl == null || (!selection.covers(decl) && decl.getParent() instanceof MethodDeclaration))
					result.add(type);
			}
		}
		return result.toArray(new ITypeBinding[result.size()]);
	}

	private void computeOutput(RefactoringStatus status) {
		// First find all writes inside the selection.
		FlowContext flowContext= new FlowContext(0, fMaxVariableId + 1);
		flowContext.setConsiderAccessMode(true);
		flowContext.setComputeMode(FlowContext.RETURN_VALUES);
		FlowInfo returnInfo= new InOutFlowAnalyzer(flowContext).perform(getSelectedNodes());
		IVariableBinding[] returnValues= returnInfo.get(flowContext, FlowInfo.WRITE | FlowInfo.WRITE_POTENTIAL | FlowInfo.UNKNOWN);

		// Compute a selection that exactly covers the selected nodes
		IRegion region= getSelectedNodeRange();
		Selection selection= Selection.createFromStartLength(region.getOffset(), region.getLength());

		List<IVariableBinding> localReads= new ArrayList<>();
		flowContext.setComputeMode(FlowContext.ARGUMENTS);
		FlowInfo argInfo= new InputFlowAnalyzer(flowContext, selection, true).perform(fEnclosingBodyDeclaration);
		IVariableBinding[] reads= argInfo.get(flowContext, FlowInfo.READ | FlowInfo.READ_POTENTIAL | FlowInfo.UNKNOWN);
		outer: for (int i= 0; i < returnValues.length && localReads.size() < returnValues.length; i++) {
			IVariableBinding binding= returnValues[i];
			for (IVariableBinding read : reads) {
				if (read == binding) {
					localReads.add(binding);
					fReturnValue= binding;
					continue outer;
				}
			}
		}
		switch (localReads.size()) {
			case 0:
				fReturnValue= null;
				break;
			case 1:
				break;
			default:
				fReturnValue= null;
				StringBuilder affectedLocals= new StringBuilder();
				for (int i= 0; i < localReads.size(); i++) {
					IVariableBinding binding= localReads.get(i);
					String bindingName= BindingLabelProvider.getBindingLabel(binding, BindingLabelProvider.DEFAULT_TEXTFLAGS | JavaElementLabels.F_PRE_TYPE_SIGNATURE);
					affectedLocals.append(bindingName);
					if (i != localReads.size() - 1) {
						affectedLocals.append('\n');
					}
				}
				String message= MessageFormat.format(RefactoringCoreMessages.ExtractMethodAnalyzer_assignments_to_local, affectedLocals.toString());
				status.addFatalError(message, JavaStatusContext.create(fCUnit, getSelection()));
				return;
		}
		List<IVariableBinding> callerLocals= new ArrayList<>(5);
		FlowInfo localInfo= new InputFlowAnalyzer(flowContext, selection, false).perform(fEnclosingBodyDeclaration);
		for (IVariableBinding write : localInfo.get(flowContext, FlowInfo.WRITE | FlowInfo.WRITE_POTENTIAL | FlowInfo.UNKNOWN)) {
			if (getSelection().covers(ASTNodes.findDeclaration(write, fEnclosingBodyDeclaration)))
				callerLocals.add(write);
		}
		fCallerLocals= callerLocals.toArray(new IVariableBinding[callerLocals.size()]);
		if (fReturnValue != null && getSelection().covers(ASTNodes.findDeclaration(fReturnValue, fEnclosingBodyDeclaration)))
			fReturnLocal= fReturnValue;
	}

	private void adjustArgumentsAndMethodLocals() {
		for (int i= 0; i < fArguments.length; i++) {
			IVariableBinding argument= fArguments[i];
			// Both arguments and locals consider FlowInfo.WRITE_POTENTIAL. But at the end a variable
			// can either be a local of an argument. Fix this based on the compute return type which
			// didn't exist when we computed the locals and arguments (see computeInput())
			if (fInputFlowInfo.hasAccessMode(fInputFlowContext, argument, FlowInfo.WRITE_POTENTIAL)) {
				if (argument != fReturnValue)
					fArguments[i]= null;
				// We didn't remove the argument. So we have to remove the local declaration
				if (fArguments[i] != null) {
					for (int l= 0; l < fMethodLocals.length; l++) {
						if (fMethodLocals[l] == argument)
							fMethodLocals[l]= null;
					}
				}
			}
		}
	}

	private void compressArrays() {
		fArguments= compressArray(fArguments);
		fCallerLocals= compressArray(fCallerLocals);
		fMethodLocals= compressArray(fMethodLocals);
	}

	private IVariableBinding[] compressArray(IVariableBinding[] array) {
		if (array == null)
			return null;
		int size= 0;
		for (IVariableBinding binding : array) {
			if (binding != null) {
				size++;
			}
		}
		if (size == array.length)
			return array;
		IVariableBinding[] result= new IVariableBinding[size];
		for (int i= 0, r= 0; i < array.length; i++) {
			if (array[i] != null)
				result[r++]= array[i];
		}
		return result;
	}

	//---- Change creation ----------------------------------------------------------------------------------

	public void aboutToCreateChange() {
	}

	//---- Exceptions -----------------------------------------------------------------------------------------

	public ITypeBinding[] getExceptions(boolean includeRuntimeExceptions) {
		if (includeRuntimeExceptions)
			return fAllExceptions;
		List<ITypeBinding> result= new ArrayList<>(fAllExceptions.length);
		for (ITypeBinding exception : fAllExceptions) {
			if (!includeRuntimeExceptions && Bindings.isRuntimeException(exception))
				continue;
			result.add(exception);
		}
		return result.toArray(new ITypeBinding[result.size()]);
	}

	private void computeExceptions() {
		fAllExceptions= ExceptionAnalyzer.perform(getSelectedNodes());
	}

	//---- Special visitor methods ---------------------------------------------------------------------------

	@Override
	protected void handleNextSelectedNode(ASTNode node) {
		super.handleNextSelectedNode(node);
		checkParent(node);
	}

	@Override
	protected boolean handleSelectionEndsIn(ASTNode node) {
		invalidSelection(RefactoringCoreMessages.StatementAnalyzer_doesNotCover, JavaStatusContext.create(fCUnit, node));
		return super.handleSelectionEndsIn(node);
	}

	private void checkParent(ASTNode node) {
		ASTNode firstParent= getFirstSelectedNode().getParent();
		do {
			node= node.getParent();
			if (node == firstParent)
				return;
		} while (node != null);
		invalidSelection(RefactoringCoreMessages.ExtractMethodAnalyzer_parent_mismatch);
	}

	@Override
	public void endVisit(CompilationUnit node) {
		RefactoringStatus status= getStatus();
		superCall: {
			if (status.hasFatalError())
				break superCall;
			if (!hasSelectedNodes()) {
				ASTNode coveringNode= getLastCoveringNode();
				if (coveringNode instanceof Block && coveringNode.getParent() instanceof MethodDeclaration) {
					MethodDeclaration methodDecl= (MethodDeclaration)coveringNode.getParent();
					Message[] messages= ASTNodes.getMessages(methodDecl, ASTNodes.NODE_ONLY);
					if (messages.length > 0) {
						status.addFatalError(Messages.format(
							RefactoringCoreMessages.ExtractMethodAnalyzer_compile_errors,
							BasicElementLabels.getJavaElementName(methodDecl.getName().getIdentifier())), JavaStatusContext.create(fCUnit, methodDecl));
						break superCall;
					}
				}
				status.addFatalError(RefactoringCoreMessages.ExtractMethodAnalyzer_invalid_selection);
				break superCall;
			}
			fEnclosingBodyDeclaration= ASTNodes.getParent(getFirstSelectedNode(), BodyDeclaration.class);
			if (fEnclosingBodyDeclaration == null ||
					(fEnclosingBodyDeclaration.getNodeType() != ASTNode.METHOD_DECLARATION &&
					 fEnclosingBodyDeclaration.getNodeType() != ASTNode.FIELD_DECLARATION &&
					 fEnclosingBodyDeclaration.getNodeType() != ASTNode.INITIALIZER)) {
				status.addFatalError(RefactoringCoreMessages.ExtractMethodAnalyzer_invalid_selection);
				break superCall;
			} else if (ASTNodes.getEnclosingType(fEnclosingBodyDeclaration) == null) {
				status.addFatalError(RefactoringCoreMessages.ExtractMethodAnalyzer_compile_errors_no_parent_binding);
				break superCall;
			} else if (fEnclosingBodyDeclaration.getNodeType() == ASTNode.METHOD_DECLARATION) {
				fEnclosingMethodBinding= ((MethodDeclaration)fEnclosingBodyDeclaration).resolveBinding();
			}
			if (!isSingleExpressionOrStatementSet()) {
				status.addFatalError(RefactoringCoreMessages.ExtractMethodAnalyzer_single_expression_or_set);
				break superCall;
			}
			if (isExpressionSelected()) {
				ASTNode expression= getFirstSelectedNode();
				if (expression instanceof Name) {
					Name name= (Name)expression;
					if (name.resolveBinding() instanceof ITypeBinding) {
						status.addFatalError(RefactoringCoreMessages.ExtractMethodAnalyzer_cannot_extract_type_reference);
						break superCall;
					}
					if (name.resolveBinding() instanceof IMethodBinding) {
						status.addFatalError(RefactoringCoreMessages.ExtractMethodAnalyzer_cannot_extract_method_name_reference);
						break superCall;
					}
					if (name.resolveBinding() instanceof IVariableBinding) {
						StructuralPropertyDescriptor locationInParent= name.getLocationInParent();
						boolean isPartOfQualifiedName= false;
						boolean isPartOfQualifier= false;
						if (locationInParent == QualifiedName.NAME_PROPERTY) {
							isPartOfQualifiedName= true;
							QualifiedName qualifiedName= (QualifiedName) name.getParent();
							QualifiedName currParent= qualifiedName;
							while (true) {
								ASTNode parent= currParent.getParent();
								if (parent instanceof QualifiedName) {
									currParent= (QualifiedName) parent;
								} else {
									break;
								}
							}
							if (!qualifiedName.equals(currParent)) {
								isPartOfQualifier= true;
							}
						}
						if ((isPartOfQualifiedName && !isPartOfQualifier)
								|| (locationInParent == FieldAccess.NAME_PROPERTY && !(((FieldAccess) name.getParent()).getExpression() instanceof ThisExpression))) {
							status.addFatalError(RefactoringCoreMessages.ExtractMethodAnalyzer_cannot_extract_part_of_qualified_name);
							break superCall;
						}
					}
					if (name.isSimpleName() && ((SimpleName)name).isDeclaration()) {
						status.addFatalError(RefactoringCoreMessages.ExtractMethodAnalyzer_cannot_extract_name_in_declaration);
						break superCall;
					}
				}
				fForceStatic=
					ASTNodes.getParent(expression, ASTNode.SUPER_CONSTRUCTOR_INVOCATION) != null ||
					ASTNodes.getParent(expression, ASTNode.CONSTRUCTOR_INVOCATION) != null;
			}
			status.merge(LocalTypeAnalyzer.perform(fEnclosingBodyDeclaration, getSelection()));
			computeLastStatementSelected();
		}
		super.endVisit(node);
	}

	@Override
	public boolean visit(AnonymousClassDeclaration node) {
		boolean result= super.visit(node);
		if (isFirstSelectedNode(node)) {
			invalidSelection(RefactoringCoreMessages.ExtractMethodAnalyzer_cannot_extract_anonymous_type, JavaStatusContext.create(fCUnit, node));
			return false;
		}
		return result;
	}

	@Override
	public boolean visit(Assignment node) {
		boolean result= super.visit(node);
		Selection selection= getSelection();
		ASTNode selectedNode= NodeFinder.perform(node, selection.getOffset(), selection.getLength());
		if ((selectedNode != null && SnippetFinder.isLeftHandSideOfAssignment(selectedNode)) || (selection.covers(node.getLeftHandSide()) && !selection.covers(node.getRightHandSide()))) {
			invalidSelection(
				RefactoringCoreMessages.ExtractMethodAnalyzer_leftHandSideOfAssignment,
				JavaStatusContext.create(fCUnit, node));
			return false;
		}
		return result;
	}

	@Override
	public boolean visit(DoStatement node) {
		boolean result= super.visit(node);

		try {
			int actionStart= getTokenScanner().getTokenEndOffset(ITerminalSymbols.TokenNamedo, node.getStartPosition());
			if (getSelection().getOffset() == actionStart) {
				invalidSelection(RefactoringCoreMessages.ExtractMethodAnalyzer_after_do_keyword, JavaStatusContext.create(fCUnit, getSelection()));
				return false;
			}
		} catch (CoreException e) {
			// ignore
		}

		return result;
	}

	@Override
	public boolean visit(LambdaExpression node) {
		Selection selection= getSelection();
		int selectionStart= selection.getOffset();
		int selectionExclusiveEnd= selection.getExclusiveEnd();
		int lambdaStart= node.getStartPosition();
		int lambdaExclusiveEnd= lambdaStart + node.getLength();
		ASTNode body= node.getBody();
		int bodyStart= body.getStartPosition();
		int bodyExclusiveEnd= bodyStart + body.getLength();

		boolean isValidSelection= false;
		if ((body instanceof Block) && (bodyStart <= selectionStart && selectionExclusiveEnd <= bodyExclusiveEnd)) {
			// if selection is inside lambda body's block
			isValidSelection= true;
		} else if (body instanceof Expression) {
			try {
				TokenScanner scanner= new TokenScanner(fCUnit);
				int arrowExclusiveEnd= scanner.getTokenEndOffset(ITerminalSymbols.TokenNameARROW, lambdaStart);
				if (selectionStart >= arrowExclusiveEnd) {
					isValidSelection= true;
				}
			} catch (CoreException e) {
				// ignore
			}
		}
		if (selectionStart <= lambdaStart && selectionExclusiveEnd >= lambdaExclusiveEnd) {
			// if selection covers the lambda node
			isValidSelection= true;
		}

		if (!isValidSelection) {
			return false;
		}
		return super.visit(node);
	}

	@Override
	public boolean visit(MethodDeclaration node) {
		Block body= node.getBody();
		if (body == null)
			return false;
		Selection selection= getSelection();
		int nodeStart= body.getStartPosition();
		int nodeExclusiveEnd= nodeStart + body.getLength();
		// if selection node inside of the method body ignore method
		if ((nodeStart >= selection.getOffset())
				|| (selection.getExclusiveEnd() >= nodeExclusiveEnd))
			return false;
		return super.visit(node);
	}

	@Override
	public boolean visit(ConstructorInvocation node) {
		return visitConstructorInvocation(node, super.visit(node));
	}

	@Override
	public boolean visit(SuperConstructorInvocation node) {
		return visitConstructorInvocation(node, super.visit(node));
	}

	private boolean visitConstructorInvocation(ASTNode node, boolean superResult) {
		if (getSelection().getVisitSelectionMode(node) == Selection.SELECTED) {
			invalidSelection(RefactoringCoreMessages.ExtractMethodAnalyzer_super_or_this, JavaStatusContext.create(fCUnit, node));
			return false;
		}
		return superResult;
	}

	@Override
	public boolean visit(VariableDeclarationFragment node) {
		boolean result= super.visit(node);
		if (isFirstSelectedNode(node)) {
			if (node.getParent() instanceof FieldDeclaration) {
				invalidSelection(RefactoringCoreMessages.ExtractMethodAnalyzer_cannot_extract_variable_declaration_fragment_from_field, JavaStatusContext.create(fCUnit, node));
			} else {
				invalidSelection(RefactoringCoreMessages.ExtractMethodAnalyzer_cannot_extract_variable_declaration_fragment, JavaStatusContext.create(fCUnit, node));
			}
			return false;
		}
		return result;
	}

	@Override
	public void endVisit(FieldDeclaration node) {
		if (contains(getSelectedNodes(), node.fragments())) {
			invalidSelection(RefactoringCoreMessages.ExtractMethodAnalyzer_cannot_extract_variable_declaration_fragment_from_field, JavaStatusContext.create(fCUnit, node));
		}
		super.endVisit(node);
	}

	@Override
	public void endVisit(ForStatement node) {
		if (getSelection().getEndVisitSelectionMode(node) == Selection.AFTER) {
			if (node.initializers().contains(getFirstSelectedNode())) {
				invalidSelection(RefactoringCoreMessages.ExtractMethodAnalyzer_cannot_extract_for_initializer, JavaStatusContext.create(fCUnit, getSelection()));
			} else if (node.updaters().contains(getLastSelectedNode())) {
				invalidSelection(RefactoringCoreMessages.ExtractMethodAnalyzer_cannot_extract_for_updater, JavaStatusContext.create(fCUnit, getSelection()));
			}
		}
		super.endVisit(node);
	}

	@Override
	public void endVisit(EnhancedForStatement node) {
		if (getSelection().getEndVisitSelectionMode(node) == Selection.AFTER) {
			if (node.getParameter() == getFirstSelectedNode()) {
				invalidSelection(RefactoringCoreMessages.ExtractMethodAnalyzer_cannot_extract_for_initializer, JavaStatusContext.create(fCUnit, getSelection()));
			}
		}
		super.endVisit(node);
	}

	@Override
	public void endVisit(QualifiedName node) {
		if (isResourceInTry(node)) {
			invalidSelection(RefactoringCoreMessages.ExtractMethodAnalyzer_resource_used_in_try_with_resources, JavaStatusContext.create(fCUnit, getSelection()));
		}
		super.endVisit(node);
	}

	@Override
	public void endVisit(BreakStatement node) {
		if (isFirstSelectedNode(node)) {
			invalidSelection(RefactoringCoreMessages.ExtractMethodAnalyzer_cannot_extract_break, JavaStatusContext.create(fCUnit, getSelection()));
		}
	}

	@Override
	public void endVisit(ContinueStatement node) {
		if (isFirstSelectedNode(node)) {
			invalidSelection(RefactoringCoreMessages.ExtractMethodAnalyzer_cannot_extract_continue, JavaStatusContext.create(fCUnit, getSelection()));
		}
	}

	@Override
	public void endVisit(YieldStatement node) {
		if (isFirstSelectedNode(node)) {
			invalidSelection(RefactoringCoreMessages.ExtractMethodAnalyzer_cannot_extract_yield, JavaStatusContext.create(fCUnit, getSelection()));
		}
		super.endVisit(node);
	}

	@Override
	public void endVisit(SimpleName node) {
		if (isResourceInTry(node)) {
			invalidSelection(RefactoringCoreMessages.ExtractMethodAnalyzer_resource_used_in_try_with_resources, JavaStatusContext.create(fCUnit, getSelection()));
		}
		super.endVisit(node);
	}

	@Override
	public void endVisit(VariableDeclarationExpression node) {
		if (isResourceInTry(node)) {
			invalidSelection(RefactoringCoreMessages.ExtractMethodAnalyzer_resource_in_try_with_resources, JavaStatusContext.create(fCUnit, getSelection()));
		}
		checkTypeInDeclaration(node.getType());
		super.endVisit(node);
	}

	@Override
	public void endVisit(VariableDeclarationStatement node) {
		checkTypeInDeclaration(node.getType());
		super.endVisit(node);
	}

	private boolean isFirstSelectedNode(ASTNode node) {
		return getSelection().getVisitSelectionMode(node) == Selection.SELECTED && getFirstSelectedNode() == node;
	}

	private void checkTypeInDeclaration(Type node) {
		if (getSelection().getEndVisitSelectionMode(node) == Selection.SELECTED && getFirstSelectedNode() == node) {
			invalidSelection(RefactoringCoreMessages.ExtractMethodAnalyzer_cannot_extract_variable_declaration, JavaStatusContext.create(fCUnit, getSelection()));
		}
	}

	private boolean isSingleExpressionOrStatementSet() {
		ASTNode first= getFirstSelectedNode();
		if (first == null)
			return true;
		if (first instanceof Expression && getSelectedNodes().length != 1)
			return false;
		return true;
	}

	private boolean isResourceInTry(Expression node) {
		return getSelection().getEndVisitSelectionMode(node) == Selection.SELECTED && getFirstSelectedNode() == node && node.getLocationInParent() == TryStatement.RESOURCES2_PROPERTY;
	}
}

