/*******************************************************************************
 * Copyright (c) 2000, 2019 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
 * 
 * This is an implementation of an early-draft specification developed under the Java
 * Community Process (JCP) and is made available for testing and evaluation purposes
 * only. The code is not compatible with any specification of the JCP.
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.core.manipulation.dom;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.IProgressMonitor;

import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
import org.eclipse.jdt.core.dom.Annotation;
import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
import org.eclipse.jdt.core.dom.ArrayAccess;
import org.eclipse.jdt.core.dom.ArrayCreation;
import org.eclipse.jdt.core.dom.ArrayInitializer;
import org.eclipse.jdt.core.dom.ArrayType;
import org.eclipse.jdt.core.dom.AssertStatement;
import org.eclipse.jdt.core.dom.Assignment;
import org.eclipse.jdt.core.dom.BodyDeclaration;
import org.eclipse.jdt.core.dom.CastExpression;
import org.eclipse.jdt.core.dom.ClassInstanceCreation;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.ConditionalExpression;
import org.eclipse.jdt.core.dom.ConstructorInvocation;
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.IBinding;
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.InfixExpression;
import org.eclipse.jdt.core.dom.Initializer;
import org.eclipse.jdt.core.dom.InstanceofExpression;
import org.eclipse.jdt.core.dom.LambdaExpression;
import org.eclipse.jdt.core.dom.MemberValuePair;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.NameQualifiedType;
import org.eclipse.jdt.core.dom.ParameterizedType;
import org.eclipse.jdt.core.dom.PrefixExpression;
import org.eclipse.jdt.core.dom.PrimitiveType;
import org.eclipse.jdt.core.dom.PrimitiveType.Code;
import org.eclipse.jdt.core.manipulation.TypeKinds;
import org.eclipse.jdt.core.dom.QualifiedName;
import org.eclipse.jdt.core.dom.QualifiedType;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.SimpleType;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
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.SuperMethodInvocation;
import org.eclipse.jdt.core.dom.SwitchCase;
import org.eclipse.jdt.core.dom.SwitchExpression;
import org.eclipse.jdt.core.dom.SwitchStatement;
import org.eclipse.jdt.core.dom.TagElement;
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.TypeLiteral;
import org.eclipse.jdt.core.dom.TypeParameter;
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.WildcardType;

import org.eclipse.jdt.internal.corext.dom.ASTNodes;
import org.eclipse.jdt.internal.corext.dom.Bindings;
import org.eclipse.jdt.internal.corext.dom.GenericVisitor;
import org.eclipse.jdt.internal.corext.dom.IASTSharedValues;
import org.eclipse.jdt.internal.corext.dom.ScopeAnalyzer;
import org.eclipse.jdt.internal.corext.dom.TypeBindingVisitor;
import org.eclipse.jdt.internal.corext.util.JdtFlags;

/**
 * Helper methods to find AST nodes or bindings.
 */
// @see JDTUIHelperClasses
// @see org.eclipse.jdt.internal.ui.text.correction.ASTResolving (subclass of this one)
public class ASTResolving {

	public static ITypeBinding guessBindingForReference(ASTNode node) {
		return Bindings.normalizeTypeBinding(getPossibleReferenceBinding(node));
	}

	private static ITypeBinding getPossibleReferenceBinding(ASTNode node) {
		ASTNode parent= node.getParent();
		switch (parent.getNodeType()) {
		case ASTNode.ASSIGNMENT:
			Assignment assignment= (Assignment) parent;
			if (node.equals(assignment.getLeftHandSide())) {
				// field write access: xx= expression
				return assignment.getRightHandSide().resolveTypeBinding();
			}
			// read access
			return assignment.getLeftHandSide().resolveTypeBinding();
		case ASTNode.INFIX_EXPRESSION:
			InfixExpression infix= (InfixExpression) parent;
			InfixExpression.Operator op= infix.getOperator();
			if (op == InfixExpression.Operator.CONDITIONAL_AND || op == InfixExpression.Operator.CONDITIONAL_OR) {
				// boolean operation
				return infix.getAST().resolveWellKnownType("boolean"); //$NON-NLS-1$
			} else if (op == InfixExpression.Operator.LEFT_SHIFT || op == InfixExpression.Operator.RIGHT_SHIFT_UNSIGNED || op == InfixExpression.Operator.RIGHT_SHIFT_SIGNED) {
				// asymmetric operation
				return infix.getAST().resolveWellKnownType("int"); //$NON-NLS-1$
			}
			if (node.equals(infix.getLeftOperand())) {
				//	xx operation expression
				ITypeBinding rigthHandBinding= infix.getRightOperand().resolveTypeBinding();
				if (rigthHandBinding != null) {
					return rigthHandBinding;
				}
			} else {
				// expression operation xx
				ITypeBinding leftHandBinding= infix.getLeftOperand().resolveTypeBinding();
				if (leftHandBinding != null) {
					return leftHandBinding;
				}
			}
			if (op != InfixExpression.Operator.EQUALS && op != InfixExpression.Operator.NOT_EQUALS) {
				return infix.getAST().resolveWellKnownType("int"); //$NON-NLS-1$
			}
			break;
		case ASTNode.INSTANCEOF_EXPRESSION:
			InstanceofExpression instanceofExpression= (InstanceofExpression) parent;
			return instanceofExpression.getRightOperand().resolveBinding();
		case ASTNode.VARIABLE_DECLARATION_FRAGMENT:
			VariableDeclarationFragment frag= (VariableDeclarationFragment) parent;
			if (frag.getInitializer().equals(node)) {
				return frag.getName().resolveTypeBinding();
			}
			break;
		case ASTNode.SUPER_METHOD_INVOCATION:
			SuperMethodInvocation superMethodInvocation= (SuperMethodInvocation) parent;
			IMethodBinding superMethodBinding= ASTNodes.getMethodBinding(superMethodInvocation.getName());
			if (superMethodBinding != null) {
				return getParameterTypeBinding(node, superMethodInvocation.arguments(), superMethodBinding);
			}
			break;
		case ASTNode.METHOD_INVOCATION:
			MethodInvocation methodInvocation= (MethodInvocation) parent;
			IMethodBinding methodBinding= methodInvocation.resolveMethodBinding();
			if (methodBinding != null) {
				return getParameterTypeBinding(node, methodInvocation.arguments(), methodBinding);
			}
			break;
		case ASTNode.SUPER_CONSTRUCTOR_INVOCATION: {
			SuperConstructorInvocation superInvocation= (SuperConstructorInvocation) parent;
			IMethodBinding superBinding= superInvocation.resolveConstructorBinding();
			if (superBinding != null) {
				return getParameterTypeBinding(node, superInvocation.arguments(), superBinding);
			}
			break;
		}
		case ASTNode.CONSTRUCTOR_INVOCATION: {
			ConstructorInvocation constrInvocation= (ConstructorInvocation) parent;
			IMethodBinding constrBinding= constrInvocation.resolveConstructorBinding();
			if (constrBinding != null) {
				return getParameterTypeBinding(node, constrInvocation.arguments(), constrBinding);
			}
			break;
		}
		case ASTNode.CLASS_INSTANCE_CREATION: {
			ClassInstanceCreation creation= (ClassInstanceCreation) parent;
			IMethodBinding creationBinding= creation.resolveConstructorBinding();
			if (creationBinding != null) {
				return getParameterTypeBinding(node, creation.arguments(), creationBinding);
			}
			break;
		}
		case ASTNode.PARENTHESIZED_EXPRESSION:
			return guessBindingForReference(parent);
		case ASTNode.ARRAY_ACCESS:
			if (((ArrayAccess) parent).getIndex().equals(node)) {
				return parent.getAST().resolveWellKnownType("int"); //$NON-NLS-1$
			} else {
				ITypeBinding parentBinding= getPossibleReferenceBinding(parent);
				if (parentBinding == null) {
					parentBinding= parent.getAST().resolveWellKnownType("java.lang.Object"); //$NON-NLS-1$
				}
				return parentBinding.createArrayType(1);
			}
		case ASTNode.ARRAY_CREATION:
			if (((ArrayCreation) parent).dimensions().contains(node)) {
				return parent.getAST().resolveWellKnownType("int"); //$NON-NLS-1$
			}
			break;
		case ASTNode.ARRAY_INITIALIZER:
			ASTNode initializerParent= parent.getParent();
			int dim= 1;
			while (initializerParent instanceof ArrayInitializer) {
				initializerParent= initializerParent.getParent();
				dim++;
			}
			Type creationType= null;
			if (initializerParent instanceof ArrayCreation) {
				creationType= ((ArrayCreation) initializerParent).getType();
			} else if (initializerParent instanceof VariableDeclaration) {
				VariableDeclaration varDecl= (VariableDeclaration) initializerParent;
				creationType= ASTNodes.getType(varDecl);
				dim-= varDecl.getExtraDimensions();
			} else if (initializerParent instanceof MemberValuePair) {
				String name= ((MemberValuePair) initializerParent).getName().getIdentifier();
				IMethodBinding annotMember= findAnnotationMember((Annotation) initializerParent.getParent(), name);
				if (annotMember != null) {
					return getReducedDimensionBinding(annotMember.getReturnType(), dim);
				}
			}
			if (creationType instanceof ArrayType) {
				ITypeBinding creationTypeBinding= ((ArrayType) creationType).resolveBinding();
				if (creationTypeBinding != null) {
					return Bindings.getComponentType(creationTypeBinding, dim);
				}
			}
			break;
		case ASTNode.CONDITIONAL_EXPRESSION:
			ConditionalExpression expression= (ConditionalExpression) parent;
			if (node.equals(expression.getExpression())) {
				return parent.getAST().resolveWellKnownType("boolean"); //$NON-NLS-1$
			}
			if (node.equals(expression.getElseExpression())) {
				return expression.getThenExpression().resolveTypeBinding();
			}
			return expression.getElseExpression().resolveTypeBinding();
		case ASTNode.POSTFIX_EXPRESSION:
			return parent.getAST().resolveWellKnownType("int"); //$NON-NLS-1$
		case ASTNode.PREFIX_EXPRESSION:
			if (((PrefixExpression) parent).getOperator() == PrefixExpression.Operator.NOT) {
				return parent.getAST().resolveWellKnownType("boolean"); //$NON-NLS-1$
			}
			return parent.getAST().resolveWellKnownType("int"); //$NON-NLS-1$
		case ASTNode.IF_STATEMENT:
		case ASTNode.WHILE_STATEMENT:
		case ASTNode.DO_STATEMENT:
			if (node instanceof Expression) {
				return parent.getAST().resolveWellKnownType("boolean"); //$NON-NLS-1$
			}
			break;
		case ASTNode.SWITCH_STATEMENT:
			if (((SwitchStatement) parent).getExpression().equals(node)) {
				return parent.getAST().resolveWellKnownType("int"); //$NON-NLS-1$
			}
			break;
		case ASTNode.RETURN_STATEMENT:
			MethodDeclaration decl= findParentMethodDeclaration(parent);
			if (decl != null && !decl.isConstructor()) {
				return decl.getReturnType2().resolveBinding();
			}
			LambdaExpression lambdaExpr= findEnclosingLambdaExpression(parent);
			if (lambdaExpr != null) {
				IMethodBinding lambdaMethodBinding= lambdaExpr.resolveMethodBinding();
				if (lambdaMethodBinding != null && lambdaMethodBinding.getReturnType() != null) {
					return lambdaMethodBinding.getReturnType();
				}
			}
			break;
		case ASTNode.CAST_EXPRESSION:
			return ((CastExpression) parent).getType().resolveBinding();
		case ASTNode.THROW_STATEMENT:
		case ASTNode.CATCH_CLAUSE:
            return parent.getAST().resolveWellKnownType("java.lang.Exception"); //$NON-NLS-1$
		case ASTNode.FIELD_ACCESS:
			if (node.equals(((FieldAccess) parent).getName())) {
				return getPossibleReferenceBinding(parent);
			}
			break;
		case ASTNode.SUPER_FIELD_ACCESS:
			return getPossibleReferenceBinding(parent);
		case ASTNode.QUALIFIED_NAME:
			if (node.equals(((QualifiedName) parent).getName())) {
				return getPossibleReferenceBinding(parent);
			}
			break;
		case ASTNode.SWITCH_CASE:
			SwitchCase switchCase= (SwitchCase) parent;
			if (node.equals(switchCase.getExpression()) || (switchCase.getAST().isPreviewEnabled() && switchCase.expressions().contains(node))) {
				ASTNode caseParent= switchCase.getParent();
				if (caseParent instanceof SwitchStatement) {
					return ((SwitchStatement) caseParent).getExpression().resolveTypeBinding();
				}
				if (caseParent instanceof SwitchExpression) {
					return ((SwitchExpression) caseParent).getExpression().resolveTypeBinding();
				}
			}
			break;
		case ASTNode.ASSERT_STATEMENT:
			if (node.getLocationInParent() == AssertStatement.EXPRESSION_PROPERTY) {
				return parent.getAST().resolveWellKnownType("boolean"); //$NON-NLS-1$
			}
			return parent.getAST().resolveWellKnownType("java.lang.String"); //$NON-NLS-1$
		case ASTNode.SINGLE_MEMBER_ANNOTATION: {
			IMethodBinding annotMember= findAnnotationMember((Annotation) parent, "value"); //$NON-NLS-1$
			if (annotMember != null) {
				return annotMember.getReturnType();
			}
			break;
		}
		case ASTNode.MEMBER_VALUE_PAIR: {
			String name= ((MemberValuePair) parent).getName().getIdentifier();
			IMethodBinding annotMember= findAnnotationMember((Annotation) parent.getParent(), name);
			if (annotMember != null) {
				return annotMember.getReturnType();
			}
			break;
		}
		default:
			// do nothing
		}

		return null;
	}

	public static IMethodBinding findAnnotationMember(Annotation annotation, String name) {
		ITypeBinding annotBinding= annotation.resolveTypeBinding();
		if (annotBinding != null) {
			return Bindings.findMethodInType(annotBinding, name, (String[]) null);
		}
		return null;
	}

	public static ITypeBinding getReducedDimensionBinding(ITypeBinding arrayBinding, int dimsToReduce) {
		while (dimsToReduce > 0) {
			arrayBinding= arrayBinding.getComponentType();
			dimsToReduce--;
		}
		return arrayBinding;
	}

	public static ITypeBinding getParameterTypeBinding(ASTNode node, List<Expression> args, IMethodBinding binding) {
		int index= args.indexOf(node);
		return getParameterTypeBinding(binding, index);
	}

	public static ITypeBinding getParameterTypeBinding(IMethodBinding methodBinding, int argumentIndex) {
		ITypeBinding[] paramTypes= methodBinding.getParameterTypes();
		if (methodBinding.isVarargs() && argumentIndex >= paramTypes.length - 1) {
			return paramTypes[paramTypes.length - 1].getComponentType();
		}
		if (argumentIndex >= 0 && argumentIndex < paramTypes.length) {
			return paramTypes[argumentIndex];
		}
		return null;
	}

    public static ITypeBinding guessBindingForTypeReference(ASTNode node) {
    	StructuralPropertyDescriptor locationInParent= node.getLocationInParent();
    	if (locationInParent == QualifiedName.QUALIFIER_PROPERTY) {
    		return null; // can't guess type for X.A
    	}
		if (locationInParent == SimpleType.NAME_PROPERTY ||
				locationInParent == NameQualifiedType.NAME_PROPERTY) {
    		node= node.getParent();
    	}
    	ITypeBinding binding= Bindings.normalizeTypeBinding(getPossibleTypeBinding(node));
    	if (binding != null) {
    		if (binding.isWildcardType()) {
    			return normalizeWildcardType(binding, true, node.getAST());
    		}
    	}
    	return binding;
    }

	private static ITypeBinding getPossibleTypeBinding(ASTNode node) {
		ASTNode parent= node.getParent();
		switch (parent.getNodeType()) {
			case ASTNode.ARRAY_TYPE: {
				int dim= ((ArrayType) parent).getDimensions();
				ITypeBinding parentBinding= getPossibleTypeBinding(parent);
				if (parentBinding != null && parentBinding.getDimensions() == dim) {
					return parentBinding.getElementType();
				}
				return null;
			}
			case ASTNode.PARAMETERIZED_TYPE: {
				ITypeBinding parentBinding= getPossibleTypeBinding(parent);
				if (parentBinding == null || !parentBinding.isParameterizedType()) {
					return null;
				}
				if (node.getLocationInParent() == ParameterizedType.TYPE_PROPERTY) {
					return parentBinding;
				}

				ITypeBinding[] typeArguments= parentBinding.getTypeArguments();
				List<Type> argumentNodes= ((ParameterizedType) parent).typeArguments();
				int index= argumentNodes.indexOf(node);
				if (index != -1 && typeArguments.length == argumentNodes.size()) {
					return typeArguments[index];
				}
				return null;
			}
			case ASTNode.WILDCARD_TYPE: {
				ITypeBinding parentBinding= getPossibleTypeBinding(parent);
				if (parentBinding == null || !parentBinding.isWildcardType()) {
					return null;
				}
				WildcardType wildcardType= (WildcardType) parent;
				if (parentBinding.isUpperbound() == wildcardType.isUpperBound()) {
					return parentBinding.getBound();
				}
				return null;
			}
			case ASTNode.QUALIFIED_TYPE: {
				ITypeBinding parentBinding= getPossibleTypeBinding(parent);
				if (parentBinding == null || !parentBinding.isMember()) {
					return null;
				}
				if (node.getLocationInParent() == QualifiedType.QUALIFIER_PROPERTY) {
					return parentBinding.getDeclaringClass();
				}
				return parentBinding;
			}
			case ASTNode.NAME_QUALIFIED_TYPE: {
				ITypeBinding parentBinding= getPossibleTypeBinding(parent);
				if (parentBinding == null || !parentBinding.isMember()) {
					return null;
				}
				if (node.getLocationInParent() == NameQualifiedType.QUALIFIER_PROPERTY) {
					return parentBinding.getDeclaringClass();
				}
				return parentBinding;
			}
			case ASTNode.VARIABLE_DECLARATION_STATEMENT:
				return guessVariableType(((VariableDeclarationStatement) parent).fragments());
			case ASTNode.FIELD_DECLARATION:
				return guessVariableType(((FieldDeclaration) parent).fragments());
			case ASTNode.VARIABLE_DECLARATION_EXPRESSION:
				return guessVariableType(((VariableDeclarationExpression) parent).fragments());
			case ASTNode.SINGLE_VARIABLE_DECLARATION:
				SingleVariableDeclaration varDecl= (SingleVariableDeclaration) parent;
				if (varDecl.getInitializer() != null) {
					return Bindings.normalizeTypeBinding(varDecl.getInitializer().resolveTypeBinding());
				}
				break;
			case ASTNode.ARRAY_CREATION:
				ArrayCreation creation= (ArrayCreation) parent;
				if (creation.getInitializer() != null) {
					return creation.getInitializer().resolveTypeBinding();
				}
				return getPossibleReferenceBinding(parent);
			case ASTNode.TYPE_LITERAL:
				return ((TypeLiteral) parent).getType().resolveBinding();
			case ASTNode.CLASS_INSTANCE_CREATION:
				return getPossibleReferenceBinding(parent);
			case ASTNode.CAST_EXPRESSION:
				return getPossibleReferenceBinding(parent);
			case ASTNode.TAG_ELEMENT:
				TagElement tagElement= (TagElement) parent;
				if (TagElement.TAG_THROWS.equals(tagElement.getTagName()) || TagElement.TAG_EXCEPTION.equals(tagElement.getTagName())) {
					ASTNode methNode= tagElement.getParent().getParent();
					if (methNode instanceof MethodDeclaration) {
						List<Type> thrownExceptions= ((MethodDeclaration) methNode).thrownExceptionTypes();
						if (thrownExceptions.size() == 1) {
							return thrownExceptions.get(0).resolveBinding();
						}
					}
				}
				break;
		}
		return null;
	}

	public static ITypeBinding guessVariableType(List<VariableDeclarationFragment> fragments) {
		for (Iterator<VariableDeclarationFragment> iter= fragments.iterator(); iter.hasNext();) {
			VariableDeclarationFragment frag= iter.next();
			if (frag.getInitializer() != null) {
				return Bindings.normalizeTypeBinding(frag.getInitializer().resolveTypeBinding());
			}
		}
		return null;
	}

   	/**
   	 * Finds all type bindings that contain a method of a given signature
   	 * @param searchRoot the ast node to start the search from
   	 * @param selector the method name
   	 * @param arguments the method arguments
   	 * @param context the context in which the method would be called
   	 * @return returns all types known in the AST that have a method with a given name
   	 */
	public static ITypeBinding[] getQualifierGuess(ASTNode searchRoot, final String selector, List<Expression> arguments, final IBinding context) {
		final int nArgs= arguments.size();
		final ArrayList<ITypeBinding> result= new ArrayList<>();

		// test if selector is a object method
		ITypeBinding binding= searchRoot.getAST().resolveWellKnownType("java.lang.Object"); //$NON-NLS-1$
		IMethodBinding[] objectMethods= binding.getDeclaredMethods();
		for (int i= 0; i < objectMethods.length; i++) {
			IMethodBinding meth= objectMethods[i];
			if (meth.getName().equals(selector) && meth.getParameterTypes().length == nArgs) {
				return new ITypeBinding[] { binding };
			}
		}

		visitAllBindings(searchRoot, new TypeBindingVisitor() {
			private HashSet<String> fVisitedBindings= new HashSet<>(100);

			@Override
			public boolean visit(ITypeBinding node) {
				node= Bindings.normalizeTypeBinding(node);
				if (node == null) {
					return true;
				}

				if (!fVisitedBindings.add(node.getKey())) {
					return true;
				}
				if (node.isGenericType()) {
					return true; // only look at  parameterized types
				}
				if (context != null && !isUseableTypeInContext(node, context, false)) {
					return true;
				}

				IMethodBinding[] methods= node.getDeclaredMethods();
				for (int i= 0; i < methods.length; i++) {
					IMethodBinding meth= methods[i];
					if (meth.getName().equals(selector) && meth.getParameterTypes().length == nArgs) {
						result.add(node);
					}
				}
				return true;
			}
		});
		return result.toArray(new ITypeBinding[result.size()]);
	}

	public static void visitAllBindings(ASTNode astRoot, TypeBindingVisitor visitor) {
		try {
			astRoot.accept(new AllBindingsVisitor(visitor));
		} catch (AllBindingsVisitor.VisitCancelledException e) {
			// visit cancelled
		}
	}

	private static class AllBindingsVisitor extends GenericVisitor {
		private final TypeBindingVisitor fVisitor;

		private static class VisitCancelledException extends RuntimeException {
			private static final long serialVersionUID= 1L;
		}
		public AllBindingsVisitor(TypeBindingVisitor visitor) {
			super(true);
			fVisitor= visitor;
		}
		@Override
		public boolean visit(SimpleName node) {
			ITypeBinding binding= node.resolveTypeBinding();
			if (binding != null) {
				boolean res= fVisitor.visit(binding);
				if (res) {
					res= Bindings.visitHierarchy(binding, fVisitor);
				}
				if (!res) {
					throw new VisitCancelledException();
				}
			}
			return false;
		}
	}


	public static IBinding getParentMethodOrTypeBinding(ASTNode node) {
		do {
			if (node instanceof MethodDeclaration) {
				return ((MethodDeclaration) node).resolveBinding();
			} else if (node instanceof AbstractTypeDeclaration) {
				return ((AbstractTypeDeclaration) node).resolveBinding();
			} else if (node instanceof AnonymousClassDeclaration) {
				return ((AnonymousClassDeclaration) node).resolveBinding();
			}
			node= node.getParent();
		} while (node != null);

		return null;
	}

	public static BodyDeclaration findParentBodyDeclaration(ASTNode node) {
		while ((node != null) && (!(node instanceof BodyDeclaration))) {
			node= node.getParent();
		}
		return (BodyDeclaration) node;
	}

	public static BodyDeclaration findParentBodyDeclaration(ASTNode node, boolean treatModifiersOutside) {
		StructuralPropertyDescriptor lastLocation= null;

		while (node != null) {
			if (node instanceof BodyDeclaration) {
				BodyDeclaration decl= (BodyDeclaration) node;
				if (!treatModifiersOutside || lastLocation != decl.getModifiersProperty()) {
					return decl;
				}
				treatModifiersOutside= false;
			}
			lastLocation= node.getLocationInParent();
			node= node.getParent();
		}
		return (BodyDeclaration) node;
	}


	public static CompilationUnit findParentCompilationUnit(ASTNode node) {
		return (CompilationUnit) findAncestor(node, ASTNode.COMPILATION_UNIT);
	}

	/**
	 * Finds the ancestor type of <code>node</code> (includes <code>node</code> in the search).
	 *
	 * @param node the node to start the search from, can be <code>null</code>
	 * @param treatModifiersOutside if set, modifiers are not part of their type, but of the type's
	 *            parent
	 * @return returns the ancestor type of <code>node</code> (AbstractTypeDeclaration or
	 *         AnonymousTypeDeclaration) if any (including <code>node</code>), <code>null</code>
	 *         otherwise
	 */
	public static ASTNode findParentType(ASTNode node, boolean treatModifiersOutside) {
		StructuralPropertyDescriptor lastLocation= null;

		while (node != null) {
			if (node instanceof AbstractTypeDeclaration) {
				AbstractTypeDeclaration decl= (AbstractTypeDeclaration) node;
				if (!treatModifiersOutside || lastLocation != decl.getModifiersProperty()) {
					return decl;
				}
			} else if (node instanceof AnonymousClassDeclaration) {
				return node;
			}
			lastLocation= node.getLocationInParent();
			node= node.getParent();
		}
		return null;
	}

	/**
	 * Finds the ancestor type of <code>node</code> (includes <code>node</code> in the search).
	 *
	 * @param node the node to start the search from, can be <code>null</code>
	 * @return returns the ancestor type of <code>node</code> (AbstractTypeDeclaration or
	 *         AnonymousTypeDeclaration) if any (including <code>node</code>), <code>null</code>
	 *         otherwise
	 */
	public static ASTNode findParentType(ASTNode node) {
		return findParentType(node, false);
	}

	/**
	 * The node's enclosing method declaration or <code>null</code> if
	 * the node is not inside a method and is not a method declaration itself.
	 * 
	 * @param node a node
	 * @return the enclosing method declaration or <code>null</code>
	 */
	public static MethodDeclaration findParentMethodDeclaration(ASTNode node) {
		while (node != null) {
			if (node instanceof MethodDeclaration) {
				return (MethodDeclaration) node;
			} else if (node instanceof BodyDeclaration || node instanceof AnonymousClassDeclaration || node instanceof LambdaExpression) {
				return null;
			}
			node= node.getParent();
		}
		return null;
	}

	/**
	 * Returns the lambda expression node which encloses the given <code>node</code>, or
	 * <code>null</code> if none.
	 * 
	 * @param node the node
	 * @return the enclosing lambda expression node for the given <code>node</code>, or
	 *         <code>null</code> if none
	 * 
	 * @since 3.10
	 */
	public static LambdaExpression findEnclosingLambdaExpression(ASTNode node) {
		node= node.getParent();
		while (node != null) {
			if (node instanceof LambdaExpression) {
				return (LambdaExpression) node;
			}
			if (node instanceof BodyDeclaration || node instanceof AnonymousClassDeclaration) {
				return null;
			}
			node= node.getParent();
		}
		return null;
	}

	/**
	 * Returns the closest ancestor of <code>node</code> (including <code>node</code> itself)
	 * whose type is <code>nodeType</code>, or <code>null</code> if none.
	 * <p>
	 * <b>Warning:</b> This method does not stop at any boundaries like parentheses, statements, body declarations, etc.
	 * The resulting node may be in a totally different scope than the given node.
	 * Consider using one of the other {@link ASTResolving}<code>.find(..)</code> methods instead.
	 * </p>
	 * @param node the node
	 * @param nodeType the node type constant from {@link ASTNode}
	 * @return the closest ancestor of <code>node</code> (including <code>node</code> itself) 
	 *         whose type is <code>nodeType</code>, or <code>null</code> if none
	 */
	public static ASTNode findAncestor(ASTNode node, int nodeType) {
		while ((node != null) && (node.getNodeType() != nodeType)) {
			node= node.getParent();
		}
		return node;
	}

	public static Statement findParentStatement(ASTNode node) {
		while ((node != null) && (!(node instanceof Statement))) {
			node= node.getParent();
			if (node instanceof BodyDeclaration) {
				return null;
			}
		}
		return (Statement) node;
	}

	public static TryStatement findParentTryStatement(ASTNode node) {
		while ((node != null) && (!(node instanceof TryStatement))) {
			node= node.getParent();
			if (node instanceof BodyDeclaration || node instanceof LambdaExpression) {
				return null;
			}
		}
		return (TryStatement) node;
	}

	public static boolean isInsideConstructorInvocation(MethodDeclaration methodDeclaration, ASTNode node) {
		if (methodDeclaration.isConstructor()) {
			Statement statement= findParentStatement(node);
			if (statement instanceof ConstructorInvocation || statement instanceof SuperConstructorInvocation) {
				return true; // argument in a this or super call
			}
		}
		return false;
	}

	public static boolean isInsideModifiers(ASTNode node) {
		while (node != null && !(node instanceof BodyDeclaration)) {
			if (node instanceof Annotation) {
				return true;
			}
			node= node.getParent();
		}
		return false;
	}

	public static boolean isInStaticContext(ASTNode selectedNode) {
		BodyDeclaration decl= findParentBodyDeclaration(selectedNode);
		if (decl instanceof MethodDeclaration) {
			if (isInsideConstructorInvocation((MethodDeclaration) decl, selectedNode)) {
				return true;
			}
			return Modifier.isStatic(decl.getModifiers());
		} else if (decl instanceof Initializer) {
			return Modifier.isStatic(((Initializer)decl).getModifiers());
		} else if (decl instanceof FieldDeclaration) {
			return JdtFlags.isStatic(decl);
		}
		return false;
	}

	public static boolean isWriteAccess(Name selectedNode) {
		ASTNode curr= selectedNode;
		ASTNode parent= curr.getParent();
		while (parent != null) {
			switch (parent.getNodeType()) {
				case ASTNode.QUALIFIED_NAME:
					if (((QualifiedName) parent).getQualifier() == curr) {
						return false;
					}
					break;
				case ASTNode.FIELD_ACCESS:
					if (((FieldAccess) parent).getExpression() == curr) {
						return false;
					}
					break;
				case ASTNode.SUPER_FIELD_ACCESS:
					break;
				case ASTNode.ASSIGNMENT:
					return ((Assignment) parent).getLeftHandSide() == curr;
				case ASTNode.VARIABLE_DECLARATION_FRAGMENT:
				case ASTNode.SINGLE_VARIABLE_DECLARATION:
					return ((VariableDeclaration) parent).getName() == curr;
				case ASTNode.POSTFIX_EXPRESSION:
					return true;
				case ASTNode.PREFIX_EXPRESSION:
					PrefixExpression.Operator op= ((PrefixExpression) parent).getOperator();
					return op == PrefixExpression.Operator.DECREMENT || op == PrefixExpression.Operator.INCREMENT;
				default:
					return false;
			}

			curr= parent;
			parent= curr.getParent();
		}
		return false;
	}

	public static String getFullName(Name name) {
		return name.getFullyQualifiedName();
	}

	public static ICompilationUnit findCompilationUnitForBinding(ICompilationUnit cu, CompilationUnit astRoot, ITypeBinding binding) throws JavaModelException {
		if (binding == null || !binding.isFromSource() || binding.isTypeVariable() || binding.isWildcardType()) {
			return null;
		}
		ASTNode node= astRoot.findDeclaringNode(binding.getTypeDeclaration());
		if (node == null) {
			ICompilationUnit targetCU= Bindings.findCompilationUnit(binding, cu.getJavaProject());
			if (targetCU != null) {
				return targetCU;
			}
			return null;
		} else if (node instanceof AbstractTypeDeclaration || node instanceof AnonymousClassDeclaration) {
			return cu;
		}
		return null;
	}


	private static final Code[] CODE_ORDER= { PrimitiveType.CHAR, PrimitiveType.SHORT, PrimitiveType.INT, PrimitiveType.LONG, PrimitiveType.FLOAT, PrimitiveType.DOUBLE };

	public static ITypeBinding[] getNarrowingTypes(AST ast, ITypeBinding type) {
		ArrayList<ITypeBinding> res= new ArrayList<>();
		res.add(type);
		if (type.isPrimitive()) {
			Code code= PrimitiveType.toCode(type.getName());
			for (int i= 0; i < CODE_ORDER.length && code != CODE_ORDER[i]; i++) {
				String typeName= CODE_ORDER[i].toString();
				res.add(ast.resolveWellKnownType(typeName));
			}
		}
		return res.toArray(new ITypeBinding[res.size()]);
	}

	public static ITypeBinding[] getRelaxingTypes(AST ast, ITypeBinding type) {
		ArrayList<ITypeBinding> res= new ArrayList<>();
		res.add(type);
		if (type.isArray()) {
			res.add(ast.resolveWellKnownType("java.lang.Object")); //$NON-NLS-1$
			// The following two types are not available in some j2me implementations, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=288060 :
			ITypeBinding serializable= ast.resolveWellKnownType("java.io.Serializable"); //$NON-NLS-1$
			if (serializable != null)
				res.add(serializable);
			ITypeBinding cloneable= ast.resolveWellKnownType("java.lang.Cloneable"); //$NON-NLS-1$
			if (cloneable != null)
				res.add(cloneable);
		} else if (type.isPrimitive()) {
			Code code= PrimitiveType.toCode(type.getName());
			boolean found= false;
			for (int i= 0; i < CODE_ORDER.length; i++) {
				if (found) {
					String typeName= CODE_ORDER[i].toString();
					res.add(ast.resolveWellKnownType(typeName));
				}
				if (code == CODE_ORDER[i]) {
					found= true;
				}
			}
		} else {
			collectRelaxingTypes(res, type);
		}
		return res.toArray(new ITypeBinding[res.size()]);
	}

	private static void collectRelaxingTypes(Collection<ITypeBinding> res, ITypeBinding type) {
		ITypeBinding[] interfaces= type.getInterfaces();
		for (int i= 0; i < interfaces.length; i++) {
			ITypeBinding curr= interfaces[i];
			if (!res.contains(curr)) {
				res.add(curr);
			}
			collectRelaxingTypes(res, curr);
		}
		ITypeBinding binding= type.getSuperclass();
		if (binding != null) {
			if (!res.contains(binding)) {
				res.add(binding);
			}
			collectRelaxingTypes(res, binding);
		}
	}

	public static String[] getUsedVariableNames(ASTNode node) {
		CompilationUnit root= (CompilationUnit) node.getRoot();
		Collection<String> res= (new ScopeAnalyzer(root)).getUsedVariableNames(node.getStartPosition(), node.getLength());
		return res.toArray(new String[res.size()]);
	}

	private static boolean isVariableDefinedInContext(IBinding binding, ITypeBinding typeVariable) {
		if (binding.getKind() == IBinding.VARIABLE) {
			IVariableBinding var= (IVariableBinding) binding;
			binding= var.getDeclaringMethod();
			if (binding == null) {
				binding= var.getDeclaringClass();
			}
		}
		if (binding instanceof IMethodBinding) {
			if (binding == typeVariable.getDeclaringMethod()) {
				return true;
			}
			binding= ((IMethodBinding) binding).getDeclaringClass();
		}

		while (binding instanceof ITypeBinding) {
			if (binding == typeVariable.getDeclaringClass()) {
				return true;
			}
			if (Modifier.isStatic(binding.getModifiers())) {
				break;
			}
			binding= ((ITypeBinding) binding).getDeclaringClass();
		}
		return false;
	}

	public static boolean isUseableTypeInContext(ITypeBinding type, IBinding context, boolean noWildcards) {
		if (type.isArray()) {
			type= type.getElementType();
		}
		if (type.isAnonymous()) {
			return false;
		}
		if (type.isRawType() || type.isPrimitive()) {
			return true;
		}
		if (type.isTypeVariable()) {
			return isVariableDefinedInContext(context, type);
		}
		if (type.isGenericType()) {
			ITypeBinding[] typeParameters= type.getTypeParameters();
			for (int i= 0; i < typeParameters.length; i++) {
				if (!isUseableTypeInContext(typeParameters[i], context, noWildcards)) {
					return false;
				}
			}
			return true;
		}
		if (type.isParameterizedType()) {
			ITypeBinding[] typeArguments= type.getTypeArguments();
			for (int i= 0; i < typeArguments.length; i++) {
				if (!isUseableTypeInContext(typeArguments[i], context, noWildcards)) {
					return false;
				}
			}
			return true;
		}
		if (type.isCapture()) {
			type= type.getWildcard();
		}

		if (type.isWildcardType()) {
			if (noWildcards) {
				return false;
			}
			if (type.getBound() != null) {
				return isUseableTypeInContext(type.getBound(), context, noWildcards);
			}
		}
		return true;
	}

	/**
	 * Use this method before creating a type for a wildcard. Either to assign a wildcard to a new type or for a type to be assigned.
	 *
	 * @param wildcardType the wildcard type to normalize
	 * @param isBindingToAssign if true, then the type X for new variable x is returned (X x= s);
	 *     if false, the type of an expression x (R r= x)
	 * @param ast the current AST
	 * @return the normalized binding or null when only the 'null' binding
	 * 
	 * @see Bindings#normalizeForDeclarationUse(ITypeBinding, AST)
	 */
	public static ITypeBinding normalizeWildcardType(ITypeBinding wildcardType, boolean isBindingToAssign, AST ast) {
		ITypeBinding bound= wildcardType.getBound();
		if (isBindingToAssign) {
			if (bound == null || !wildcardType.isUpperbound()) {
				ITypeBinding[] typeBounds= wildcardType.getTypeBounds();
				if (typeBounds.length > 0) {
					return typeBounds[0];
				} else {
					return wildcardType.getErasure();
				}
			}
		} else {
			if (bound == null || wildcardType.isUpperbound()) {
				return null;
			}
		}
		return bound;
	}


	public static CompilationUnit createQuickFixAST(ICompilationUnit compilationUnit, IProgressMonitor monitor) {
		ASTParser astParser= ASTParser.newParser(IASTSharedValues.SHARED_AST_LEVEL);
		astParser.setSource(compilationUnit);
		astParser.setResolveBindings(true);
		astParser.setStatementsRecovery(IASTSharedValues.SHARED_AST_STATEMENT_RECOVERY);
		astParser.setBindingsRecovery(IASTSharedValues.SHARED_BINDING_RECOVERY);
		return (CompilationUnit) astParser.createAST(monitor);
	}

	public static int getPossibleTypeKinds(ASTNode node, boolean is50OrHigher) {
		int kinds= internalGetPossibleTypeKinds(node);
		if (!is50OrHigher) {
			kinds &= (TypeKinds.INTERFACES | TypeKinds.CLASSES);
		}
		return kinds;
	}

	private static int internalGetPossibleTypeKinds(ASTNode node) {
		int kind= TypeKinds.ALL_TYPES;

		int mask= TypeKinds.ALL_TYPES | TypeKinds.VOIDTYPE;

		ASTNode parent= node.getParent();
		while (parent instanceof QualifiedName) {
			if (node.getLocationInParent() == QualifiedName.QUALIFIER_PROPERTY) {
				return TypeKinds.REF_TYPES;
			}
			node= parent;
			parent= parent.getParent();
			mask= TypeKinds.REF_TYPES;
		}
		while (parent instanceof Type) {
			if (parent instanceof QualifiedType) {
				if (node.getLocationInParent() == QualifiedType.QUALIFIER_PROPERTY) {
					return mask & (TypeKinds.REF_TYPES);
				}
				mask&= TypeKinds.REF_TYPES;
			} else if (parent instanceof NameQualifiedType) {
				if (node.getLocationInParent() == NameQualifiedType.QUALIFIER_PROPERTY) {
					return mask & (TypeKinds.REF_TYPES);
				}
				mask&= TypeKinds.REF_TYPES;
			} else if (parent instanceof ParameterizedType) {
				if (node.getLocationInParent() == ParameterizedType.TYPE_ARGUMENTS_PROPERTY) {
					return mask & TypeKinds.REF_TYPES_AND_VAR;
				}
				mask&= TypeKinds.CLASSES | TypeKinds.INTERFACES;
			} else if (parent instanceof WildcardType) {
				if (node.getLocationInParent() == WildcardType.BOUND_PROPERTY) {
					return mask & TypeKinds.REF_TYPES_AND_VAR;
				}
			}
			node= parent;
			parent= parent.getParent();
		}

		if (parent != null) {
			switch (parent.getNodeType()) {
				case ASTNode.TYPE_DECLARATION:
					if (node.getLocationInParent() == TypeDeclaration.SUPER_INTERFACE_TYPES_PROPERTY) {
						kind= TypeKinds.INTERFACES;
					} else if (node.getLocationInParent() == TypeDeclaration.SUPERCLASS_TYPE_PROPERTY) {
						kind= TypeKinds.CLASSES;
					}
					break;
				case ASTNode.ENUM_DECLARATION:
					kind= TypeKinds.INTERFACES;
					break;
				case ASTNode.METHOD_DECLARATION:
					if (node.getLocationInParent() == MethodDeclaration.THROWN_EXCEPTION_TYPES_PROPERTY) {
						kind= TypeKinds.CLASSES;
					} else if (node.getLocationInParent() == MethodDeclaration.RETURN_TYPE2_PROPERTY) {
						kind= TypeKinds.ALL_TYPES | TypeKinds.VOIDTYPE;
					}
					break;
				case ASTNode.ANNOTATION_TYPE_MEMBER_DECLARATION:
					kind= TypeKinds.PRIMITIVETYPES | TypeKinds.ANNOTATIONS | TypeKinds.ENUMS;
					break;
				case ASTNode.INSTANCEOF_EXPRESSION:
					kind= TypeKinds.REF_TYPES;
					break;
				case ASTNode.THROW_STATEMENT:
					kind= TypeKinds.CLASSES;
					break;
				case ASTNode.CLASS_INSTANCE_CREATION:
					if (((ClassInstanceCreation) parent).getAnonymousClassDeclaration() == null) {
						kind= TypeKinds.CLASSES;
					} else {
						kind= TypeKinds.CLASSES | TypeKinds.INTERFACES;
					}
					break;
				case ASTNode.SINGLE_VARIABLE_DECLARATION:
					int superParent= parent.getParent().getNodeType();
					if (superParent == ASTNode.CATCH_CLAUSE) {
						kind= TypeKinds.CLASSES;
					} else if (superParent == ASTNode.ENHANCED_FOR_STATEMENT) {
						kind= TypeKinds.REF_TYPES;
					}
					break;
				case ASTNode.TAG_ELEMENT:
					kind= TypeKinds.REF_TYPES;
					break;
				case ASTNode.MARKER_ANNOTATION:
				case ASTNode.SINGLE_MEMBER_ANNOTATION:
				case ASTNode.NORMAL_ANNOTATION:
					kind= TypeKinds.ANNOTATIONS;
					break;
				case ASTNode.TYPE_PARAMETER:
					if (((TypeParameter) parent).typeBounds().indexOf(node) > 0) {
						kind= TypeKinds.INTERFACES;
					} else {
						kind= TypeKinds.REF_TYPES_AND_VAR;
					}
					break;
				case ASTNode.TYPE_LITERAL:
					kind= TypeKinds.REF_TYPES;
					break;
				default:
			}
		}
		return kind & mask;
	}
}
