/*******************************************************************************
 * Copyright (c) 2000, 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.eval;

import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
import org.eclipse.jdt.internal.compiler.lookup.Binding;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
import org.eclipse.jdt.internal.compiler.lookup.InvocationSite;
import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
import org.eclipse.jdt.internal.compiler.lookup.ProblemBinding;
import org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding;
import org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding;
import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
import org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.Scope;
import org.eclipse.jdt.internal.compiler.lookup.TagBits;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.eclipse.jdt.internal.compiler.lookup.VariableBinding;
import org.eclipse.jdt.internal.compiler.util.ObjectVector;

/**
 * This scope is used for code snippet lookup to emulate private, protected and default access.
 * These accesses inside inner classes are not managed yet.
 */
public class CodeSnippetScope extends BlockScope {
/**
 * CodeSnippetScope constructor comment.
 * @param kind int
 * @param parent org.eclipse.jdt.internal.compiler.lookup.Scope
 */
protected CodeSnippetScope(int kind, Scope parent) {
	super(kind, parent);
}
/**
 * CodeSnippetScope constructor comment.
 * @param parent org.eclipse.jdt.internal.compiler.lookup.BlockScope
 */
public CodeSnippetScope(BlockScope parent) {
	super(parent);
}
/**
 * CodeSnippetScope constructor comment.
 * @param parent org.eclipse.jdt.internal.compiler.lookup.BlockScope
 * @param variableCount int
 */
public CodeSnippetScope(BlockScope parent, int variableCount) {
	super(parent, variableCount);
}
/* Answer true if the receiver is visible to the type provided by the scope.
* InvocationSite implements isSuperAccess() to provide additional information
* if the receiver is protected.
*
* NOTE: Cannot invoke this method with a compilation unit scope.
*/

public final boolean canBeSeenByForCodeSnippet(FieldBinding fieldBinding, TypeBinding receiverType, InvocationSite invocationSite, Scope scope) {
	if (fieldBinding.isPublic()) return true;

	ReferenceBinding invocationType = (ReferenceBinding) receiverType;
	if (invocationType == fieldBinding.declaringClass) return true;

	if (fieldBinding.isProtected()) {
		// answer true if the invocationType is the declaringClass or they are in the same package
		// OR the invocationType is a subclass of the declaringClass
		//    AND the receiverType is the invocationType or its subclass
		//    OR the field is a static field accessed directly through a type
		if (invocationType == fieldBinding.declaringClass) return true;
		if (invocationType.fPackage == fieldBinding.declaringClass.fPackage) return true;
		if (fieldBinding.declaringClass.isSuperclassOf(invocationType)) {
			if (invocationSite.isSuperAccess()) return true;
			// receiverType can be an array binding in one case... see if you can change it
			if (receiverType instanceof ArrayBinding)
				return false;
			if (invocationType == receiverType || invocationType.isSuperclassOf((ReferenceBinding) receiverType))
				return true;
			if (fieldBinding.isStatic())
				return true; // see 1FMEPDL - return invocationSite.isTypeAccess();
		}
		return false;
	}

	if (fieldBinding.isPrivate()) {
		// answer true if the receiverType is the declaringClass
		// AND the invocationType and the declaringClass have a common enclosingType
		if (receiverType != fieldBinding.declaringClass) return false;

		if (invocationType != fieldBinding.declaringClass) {
			ReferenceBinding outerInvocationType = invocationType;
			ReferenceBinding temp = outerInvocationType.enclosingType();
			while (temp != null) {
				outerInvocationType = temp;
				temp = temp.enclosingType();
			}

			ReferenceBinding outerDeclaringClass = fieldBinding.declaringClass;
			temp = outerDeclaringClass.enclosingType();
			while (temp != null) {
				outerDeclaringClass = temp;
				temp = temp.enclosingType();
			}
			if (outerInvocationType != outerDeclaringClass) return false;
		}
		return true;
	}

	// isDefault()
	if (invocationType.fPackage != fieldBinding.declaringClass.fPackage) return false;

	// receiverType can be an array binding in one case... see if you can change it
	if (receiverType instanceof ArrayBinding)
		return false;
	ReferenceBinding type = (ReferenceBinding) receiverType;
	PackageBinding declaringPackage = fieldBinding.declaringClass.fPackage;
	do {
		if (fieldBinding.declaringClass == type) return true;
		if (declaringPackage != type.fPackage) return false;
	} while ((type = type.superclass()) != null);
	return false;
}
/* Answer true if the receiver is visible to the type provided by the scope.
* InvocationSite implements isSuperAccess() to provide additional information
* if the receiver is protected.
*
* NOTE: Cannot invoke this method with a compilation unit scope.
*/
public final boolean canBeSeenByForCodeSnippet(MethodBinding methodBinding, TypeBinding receiverType, InvocationSite invocationSite, Scope scope) {
	if (methodBinding.isPublic()) return true;

	ReferenceBinding invocationType = (ReferenceBinding) receiverType;
	if (invocationType == methodBinding.declaringClass && invocationType == receiverType) return true;

	if (methodBinding.isProtected()) {
		// answer true if the invocationType is the declaringClass or they are in the same package
		// OR the invocationType is a subclass of the declaringClass
		//    AND the receiverType is the invocationType or its subclass
		//    OR the method is a static method accessed directly through a type
		if (invocationType == methodBinding.declaringClass) return true;
		if (invocationType.fPackage == methodBinding.declaringClass.fPackage) return true;
		if (methodBinding.declaringClass.isSuperclassOf(invocationType)) {
			if (invocationSite.isSuperAccess()) return true;
			// receiverType can be an array binding in one case... see if you can change it
			if (receiverType instanceof ArrayBinding)
				return false;
			if (invocationType == receiverType || invocationType.isSuperclassOf((ReferenceBinding) receiverType))
				return true;
			if (methodBinding.isStatic())
				return true; // see 1FMEPDL - return invocationSite.isTypeAccess();
		}
		return false;
	}

	if (methodBinding.isPrivate()) {
		// answer true if the receiverType is the declaringClass
		// AND the invocationType and the declaringClass have a common enclosingType
		if (receiverType != methodBinding.declaringClass) return false;

		if (invocationType != methodBinding.declaringClass) {
			ReferenceBinding outerInvocationType = invocationType;
			ReferenceBinding temp = outerInvocationType.enclosingType();
			while (temp != null) {
				outerInvocationType = temp;
				temp = temp.enclosingType();
			}

			ReferenceBinding outerDeclaringClass = methodBinding.declaringClass;
			temp = outerDeclaringClass.enclosingType();
			while (temp != null) {
				outerDeclaringClass = temp;
				temp = temp.enclosingType();
			}
			if (outerInvocationType != outerDeclaringClass) return false;
		}
		return true;
	}

	// isDefault()
	if (invocationType.fPackage != methodBinding.declaringClass.fPackage) return false;

	// receiverType can be an array binding in one case... see if you can change it
	if (receiverType instanceof ArrayBinding)
		return false;
	ReferenceBinding type = (ReferenceBinding) receiverType;
	PackageBinding declaringPackage = methodBinding.declaringClass.fPackage;
	do {
		if (methodBinding.declaringClass == type) return true;
		if (declaringPackage != type.fPackage) return false;
	} while ((type = type.superclass()) != null);
	return false;
}
/* Answer true if the receiver is visible to the type provided by the scope.
* InvocationSite implements isSuperAccess() to provide additional information
* if the receiver is protected.
*
* NOTE: Cannot invoke this method with a compilation unit scope.
*/

public final boolean canBeSeenByForCodeSnippet(ReferenceBinding referenceBinding, ReferenceBinding receiverType) {
	if (referenceBinding.isPublic()) return true;

	if (receiverType == referenceBinding) return true;

	if (referenceBinding.isProtected()) {
		// answer true if the receiver (or its enclosing type) is the superclass 
		//	of the receiverType or in the same package
		return receiverType.fPackage == referenceBinding.fPackage 
				|| referenceBinding.isSuperclassOf(receiverType)
				|| referenceBinding.enclosingType().isSuperclassOf(receiverType); // protected types always have an enclosing one
	}

	if (referenceBinding.isPrivate()) {
		// answer true if the receiver and the receiverType have a common enclosingType
		// already know they are not the identical type
		ReferenceBinding outerInvocationType = receiverType;
		ReferenceBinding temp = outerInvocationType.enclosingType();
		while (temp != null) {
			outerInvocationType = temp;
			temp = temp.enclosingType();
		}

		ReferenceBinding outerDeclaringClass = referenceBinding;
		temp = outerDeclaringClass.enclosingType();
		while (temp != null) {
			outerDeclaringClass = temp;
			temp = temp.enclosingType();
		}
		return outerInvocationType == outerDeclaringClass;
	}

	// isDefault()
	return receiverType.fPackage == referenceBinding.fPackage;
}
// Internal use only
public MethodBinding findExactMethod(ReferenceBinding receiverType, char[] selector, TypeBinding[] argumentTypes, InvocationSite invocationSite) {
	MethodBinding exactMethod = receiverType.getExactMethod(selector, argumentTypes, null);
	if (exactMethod != null){
		if (receiverType.isInterface() || canBeSeenByForCodeSnippet(exactMethod, receiverType, invocationSite, this))
			return exactMethod;
	}
	return null;
}
// Internal use only

/*	Answer the field binding that corresponds to fieldName.
	Start the lookup at the receiverType.
	InvocationSite implements
		isSuperAccess(); this is used to determine if the discovered field is visible.
	Only fields defined by the receiverType or its supertypes are answered;
	a field of an enclosing type will not be found using this API.

	If no visible field is discovered, null is answered.
*/

public FieldBinding findFieldForCodeSnippet(TypeBinding receiverType, char[] fieldName, InvocationSite invocationSite) {
	if (receiverType.isBaseType())
		return null;
	if (receiverType.isArrayType()) {
		TypeBinding leafType = receiverType.leafComponentType();
		if (leafType instanceof ReferenceBinding)
		if (!((ReferenceBinding)leafType).canBeSeenBy(this)) {
			return new ProblemFieldBinding((ReferenceBinding)leafType, fieldName, ProblemReasons.ReceiverTypeNotVisible);
		}
		if (CharOperation.equals(fieldName, LENGTH))
			return ArrayBinding.ArrayLength;
		return null;
	}

	ReferenceBinding currentType = (ReferenceBinding) receiverType;
	if (!currentType.canBeSeenBy(this))
		return new ProblemFieldBinding(currentType, fieldName, ProblemReasons.ReceiverTypeNotVisible);

	FieldBinding field = currentType.getField(fieldName, true /*resolve*/);
	if (field != null) {
		if (canBeSeenByForCodeSnippet(field, currentType, invocationSite, this))
			return field;
		else
			return new ProblemFieldBinding(field /* closest match*/, field.declaringClass, fieldName, ProblemReasons.NotVisible);
	}

	// collect all superinterfaces of receiverType until the field is found in a supertype
	ReferenceBinding[][] interfacesToVisit = null;
	int lastPosition = -1;
	FieldBinding visibleField = null;
	boolean keepLooking = true;
	boolean notVisible = false; // we could hold onto the not visible field for extra error reporting
	while (keepLooking) {
		ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
		if (itsInterfaces != NoSuperInterfaces) {
			if (interfacesToVisit == null)
				interfacesToVisit = new ReferenceBinding[5][];
			if (++lastPosition == interfacesToVisit.length)
				System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, lastPosition);
			interfacesToVisit[lastPosition] = itsInterfaces;
		}
		if ((currentType = currentType.superclass()) == null)
			break;

		if ((field = currentType.getField(fieldName, true /*resolve*/)) != null) {
			keepLooking = false;
			if (canBeSeenByForCodeSnippet(field, receiverType, invocationSite, this)) {
				if (visibleField == null)
					visibleField = field;
				else
					return new ProblemFieldBinding(visibleField.declaringClass, fieldName, ProblemReasons.Ambiguous);
			} else {
				notVisible = true;
			}
		}
	}

	// walk all visible interfaces to find ambiguous references
	if (interfacesToVisit != null) {
		ProblemFieldBinding ambiguous = null;
		done : for (int i = 0; i <= lastPosition; i++) {
			ReferenceBinding[] interfaces = interfacesToVisit[i];
			for (int j = 0, length = interfaces.length; j < length; j++) {
				ReferenceBinding anInterface = interfaces[j];
				if ((anInterface.tagBits & TagBits.InterfaceVisited) == 0) { // if interface as not already been visited
					anInterface.tagBits |= TagBits.InterfaceVisited;
					if ((field = anInterface.getField(fieldName, true /*resolve*/)) != null) {
						if (visibleField == null) {
							visibleField = field;
						} else {
							ambiguous = new ProblemFieldBinding(visibleField.declaringClass, fieldName, ProblemReasons.Ambiguous);
							break done;
						}
					} else {
						ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
						if (itsInterfaces != NoSuperInterfaces) {
							if (++lastPosition == interfacesToVisit.length)
								System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, lastPosition);
							interfacesToVisit[lastPosition] = itsInterfaces;
						}
					}
				}
			}
		}

		// bit reinitialization
		for (int i = 0; i <= lastPosition; i++) {
			ReferenceBinding[] interfaces = interfacesToVisit[i];
			for (int j = 0, length = interfaces.length; j < length; j++)
				interfaces[j].tagBits &= ~TagBits.InterfaceVisited;
		}
		if (ambiguous != null) return ambiguous;
	}

	if (visibleField != null)
		return visibleField;
	if (notVisible)
		return new ProblemFieldBinding(currentType, fieldName, ProblemReasons.NotVisible);
	return null;
}
// Internal use only
public MethodBinding findMethod(
	ReferenceBinding receiverType,
	char[] selector,
	TypeBinding[] argumentTypes,
	InvocationSite invocationSite) {

		ReferenceBinding currentType = receiverType;
		MethodBinding matchingMethod = null;
		ObjectVector found = new ObjectVector();

		//compilationUnitScope().recordTypeReference(receiverType);
		//compilationUnitScope().recordTypeReferences(argumentTypes);

		if (currentType.isInterface()) {
			MethodBinding[] currentMethods = currentType.getMethods(selector);
			int currentLength = currentMethods.length;
			if (currentLength == 1) {
				matchingMethod = currentMethods[0];
			} else if (currentLength > 1) {
				for (int f = 0; f < currentLength; f++)
					found.add(currentMethods[f]);
			}
			matchingMethod = findMethodInSuperInterfaces(currentType, selector, found, matchingMethod);
			currentType = getJavaLangObject();
		}

		// superclass lookup
		ReferenceBinding classHierarchyStart = currentType;
		
		while (currentType != null) {
			MethodBinding[] currentMethods = currentType.getMethods(selector);
			int currentLength = currentMethods.length;
			if (currentLength == 1 && matchingMethod == null && found.size == 0) {
				matchingMethod = currentMethods[0];
			} else if (currentLength > 0) {
				if (found.size == 0 && matchingMethod != null)
					found.add(matchingMethod);
				for (int f = 0; f < currentLength; f++)
					found.add(currentMethods[f]);
			}
			currentType = currentType.superclass();
		}

		int foundSize = found.size;
		if (foundSize == 0) {
			if (matchingMethod == null){
				MethodBinding interfaceMethod = findDefaultAbstractMethod(receiverType, selector, argumentTypes, invocationSite, classHierarchyStart, matchingMethod, found);
				if (interfaceMethod != null) return interfaceMethod;
			}
			return matchingMethod; // may be null - have not checked arg types or visibility
		}
		MethodBinding[] candidates = new MethodBinding[foundSize];
		int candidatesCount = 0;

		// argument type compatibility check
		for (int i = 0; i < foundSize; i++) {
			MethodBinding methodBinding = (MethodBinding) found.elementAt(i);
			MethodBinding compatibleMethod = computeCompatibleMethod(methodBinding, argumentTypes, invocationSite);
			if (compatibleMethod != null)
				candidates[candidatesCount++] = compatibleMethod;
		}
		if (candidatesCount == 1) {
			//compilationUnitScope().recordTypeReferences(candidates[0].thrownExceptions);
			return candidates[0]; // have not checked visibility
		}
		if (candidatesCount == 0) { // try to find a close match when the parameter order is wrong or missing some parameters
			MethodBinding interfaceMethod = findDefaultAbstractMethod(receiverType, selector, argumentTypes, invocationSite, classHierarchyStart, matchingMethod, found);
			if (interfaceMethod != null) return interfaceMethod;

			int argLength = argumentTypes.length;
			foundSize = found.size;
			nextMethod : for (int i = 0; i < foundSize; i++) {
				MethodBinding methodBinding = (MethodBinding) found.elementAt(i);
				TypeBinding[] params = methodBinding.parameters;
				int paramLength = params.length;
				nextArg: for (int a = 0; a < argLength; a++) {
					TypeBinding arg = argumentTypes[a];
					for (int p = 0; p < paramLength; p++)
						if (params[p] == arg)
							continue nextArg;
					continue nextMethod;
				}
				return methodBinding;
			}
			return (MethodBinding) found.elementAt(0); // no good match so just use the first one found
		}

		// visibility check
		int visiblesCount = 0;
		for (int i = 0; i < candidatesCount; i++) {
			MethodBinding methodBinding = candidates[i];
			if (canBeSeenByForCodeSnippet(methodBinding, receiverType, invocationSite, this)) {
				if (visiblesCount != i) {
					candidates[i] = null;
					candidates[visiblesCount] = methodBinding;
				}
				visiblesCount++;
			}
		}
		if (visiblesCount == 1) {
			//compilationUnitScope().recordTypeReferences(candidates[0].thrownExceptions);
			return candidates[0];
		}
		if (visiblesCount == 0) {
			MethodBinding interfaceMethod = findDefaultAbstractMethod(receiverType, selector, argumentTypes, invocationSite, classHierarchyStart, matchingMethod, found);
			if (interfaceMethod != null) return interfaceMethod;
			return new ProblemMethodBinding(
				candidates[0].selector,
				candidates[0].parameters,
				candidates[0].declaringClass,
				ProblemReasons.NotVisible);
		}	
		if (!candidates[0].declaringClass.isInterface()) {
			return mostSpecificClassMethodBinding(candidates, visiblesCount, invocationSite);
		} else {
			return mostSpecificInterfaceMethodBinding(candidates, visiblesCount, invocationSite);
		}
	}

// Internal use only
public MethodBinding findMethodForArray(ArrayBinding receiverType, char[] selector, TypeBinding[] argumentTypes, InvocationSite invocationSite) {
	ReferenceBinding object = getJavaLangObject();
	MethodBinding methodBinding = object.getExactMethod(selector, argumentTypes, null);
	if (methodBinding != null) {
		// handle the method clone() specially... cannot be protected or throw exceptions
		if (argumentTypes == NoParameters && CharOperation.equals(selector, CLONE))
			return new MethodBinding((methodBinding.modifiers & ~ClassFileConstants.AccProtected) | ClassFileConstants.AccPublic, CLONE, methodBinding.returnType, argumentTypes, null, object);
		if (canBeSeenByForCodeSnippet(methodBinding, receiverType, invocationSite, this))
			return methodBinding;
	}

	// answers closest approximation, may not check argumentTypes or visibility
	methodBinding = findMethod(object, selector, argumentTypes, invocationSite);
	if (methodBinding == null)
		return new ProblemMethodBinding(selector, argumentTypes, ProblemReasons.NotFound);
	if (methodBinding.isValidBinding()) {
	    MethodBinding compatibleMethod = computeCompatibleMethod(methodBinding, argumentTypes, invocationSite);
	    if (compatibleMethod == null)
			return new ProblemMethodBinding(methodBinding, selector, argumentTypes, ProblemReasons.NotFound);
	    methodBinding = compatibleMethod;
		if (!canBeSeenByForCodeSnippet(methodBinding, receiverType, invocationSite, this))
			return new ProblemMethodBinding(methodBinding, selector, methodBinding.parameters, ProblemReasons.NotVisible);
	}
	return methodBinding;
}
/* API
	flag is a mask of the following values VARIABLE (= FIELD or LOCAL), TYPE.
	Only bindings corresponding to the mask will be answered.

	if the VARIABLE mask is set then
		If the first name provided is a field (or local) then the field (or local) is answered
		Otherwise, package names and type names are consumed until a field is found.
		In this case, the field is answered.

	if the TYPE mask is set,
		package names and type names are consumed until the end of the input.
		Only if all of the input is consumed is the type answered

	All other conditions are errors, and a problem binding is returned.
	
	NOTE: If a problem binding is returned, senders should extract the compound name
	from the binding & not assume the problem applies to the entire compoundName.

	The VARIABLE mask has precedence over the TYPE mask.

	InvocationSite implements
		isSuperAccess(); this is used to determine if the discovered field is visible.
		setFieldIndex(int); this is used to record the number of names that were consumed.

	For example, getBinding({"foo","y","q", VARIABLE, site) will answer
	the binding for the field or local named "foo" (or an error binding if none exists).
	In addition, setFieldIndex(1) will be sent to the invocation site.
	If a type named "foo" exists, it will not be detected (and an error binding will be answered)

	IMPORTANT NOTE: This method is written under the assumption that compoundName is longer than length 1.
*/

public Binding getBinding(char[][] compoundName, int mask, InvocationSite invocationSite, ReferenceBinding receiverType) {
	Binding binding = getBinding(compoundName[0], mask | Binding.TYPE | Binding.PACKAGE, invocationSite, true /*resolve*/);
	invocationSite.setFieldIndex(1);
	if (!binding.isValidBinding() || binding instanceof VariableBinding)
		return binding;

	int length = compoundName.length;
	int currentIndex = 1;
	foundType: if (binding instanceof PackageBinding) {
		PackageBinding packageBinding = (PackageBinding) binding;

		while (currentIndex < length) {
			binding = packageBinding.getTypeOrPackage(compoundName[currentIndex++]);
			invocationSite.setFieldIndex(currentIndex);
 			if (binding == null) {
	 			if (currentIndex == length) // must be a type if its the last name, otherwise we have no idea if its a package or type
					return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, currentIndex), null, ProblemReasons.NotFound);
				else
					return new ProblemBinding(CharOperation.subarray(compoundName, 0, currentIndex), ProblemReasons.NotFound);
 			}
 			if (binding instanceof ReferenceBinding) {
	 			if (!binding.isValidBinding())
					return new ProblemReferenceBinding(
									CharOperation.subarray(compoundName, 0, currentIndex), 
									null, // TODO should improve
									binding.problemId());
	 			if (!this.canBeSeenByForCodeSnippet((ReferenceBinding) binding, receiverType))
					return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, currentIndex), (ReferenceBinding) binding, ProblemReasons.NotVisible);
	 			break foundType;
 			}
 			packageBinding = (PackageBinding) binding;
		}

		// It is illegal to request a PACKAGE from this method.
		return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, currentIndex), null, ProblemReasons.NotFound);
	}

	// know binding is now a ReferenceBinding
	while (currentIndex < length) {
		ReferenceBinding typeBinding = (ReferenceBinding) binding;
		char[] nextName = compoundName[currentIndex++];
		invocationSite.setFieldIndex(currentIndex);
		if ((binding = findFieldForCodeSnippet(typeBinding, nextName, invocationSite)) != null) {
			if (!binding.isValidBinding())
				return new ProblemFieldBinding((FieldBinding)binding, CharOperation.subarray(compoundName, 0, currentIndex), binding.problemId());
			break; // binding is now a field
		}
		if ((binding = findMemberType(nextName, typeBinding)) == null)
			return new ProblemBinding(CharOperation.subarray(compoundName, 0, currentIndex), typeBinding, ProblemReasons.NotFound);
		 if (!binding.isValidBinding())
			return new ProblemReferenceBinding(
								CharOperation.subarray(compoundName, 0, currentIndex), 
								null, // TODO should improve
								binding.problemId());
	}

	if ((mask & Binding.FIELD) != 0 && (binding instanceof FieldBinding)) { // was looking for a field and found a field
		FieldBinding field = (FieldBinding) binding;
		if (!field.isStatic())
			return new ProblemFieldBinding(field, CharOperation.subarray(compoundName, 0, currentIndex), ProblemReasons.NonStaticReferenceInStaticContext);
		return binding;
	}
	if ((mask & Binding.TYPE) != 0 && (binding instanceof ReferenceBinding)) { // was looking for a type and found a type
		return binding;
	}

	// handle the case when a field or type was asked for but we resolved the compoundName to a type or field
	return new ProblemBinding(CharOperation.subarray(compoundName, 0, currentIndex), ProblemReasons.NotFound);
}
/* API

	Answer the constructor binding that corresponds to receiverType, argumentTypes.

	InvocationSite implements 
		isSuperAccess(); this is used to determine if the discovered constructor is visible.

	If no visible constructor is discovered, an error binding is answered.
*/

public MethodBinding getConstructor(ReferenceBinding receiverType, TypeBinding[] argumentTypes, InvocationSite invocationSite) {
	MethodBinding methodBinding = receiverType.getExactConstructor(argumentTypes);
	if (methodBinding != null) {
		if (canBeSeenByForCodeSnippet(methodBinding, receiverType, invocationSite, this)) {
			return methodBinding;
		}
	}
	MethodBinding[] methods = receiverType.getMethods(TypeConstants.INIT);
	if (methods == NoMethods) {
		return new ProblemMethodBinding(TypeConstants.INIT, argumentTypes, ProblemReasons.NotFound);
	}
	MethodBinding[] compatible = new MethodBinding[methods.length];
	int compatibleIndex = 0;
	for (int i = 0, length = methods.length; i < length; i++) {
	    MethodBinding compatibleMethod = computeCompatibleMethod(methods[i], argumentTypes, invocationSite);
		if (compatibleMethod != null)
			compatible[compatibleIndex++] = compatibleMethod;
	}
	if (compatibleIndex == 0)
		return new ProblemMethodBinding(TypeConstants.INIT, argumentTypes, ProblemReasons.NotFound); // need a more descriptive error... cannot convert from X to Y

	MethodBinding[] visible = new MethodBinding[compatibleIndex];
	int visibleIndex = 0;
	for (int i = 0; i < compatibleIndex; i++) {
		MethodBinding method = compatible[i];
		if (canBeSeenByForCodeSnippet(method, receiverType, invocationSite, this)) {
			visible[visibleIndex++] = method;
		}
	}
	if (visibleIndex == 1) {
		return visible[0];
	}
	if (visibleIndex == 0) {
		return new ProblemMethodBinding(compatible[0], TypeConstants.INIT, compatible[0].parameters, ProblemReasons.NotVisible);
	}
	return mostSpecificClassMethodBinding(visible, visibleIndex, invocationSite);
}
/* API

	Answer the field binding that corresponds to fieldName.
	Start the lookup at the receiverType.
	InvocationSite implements
		isSuperAccess(); this is used to determine if the discovered field is visible.
	Only fields defined by the receiverType or its supertypes are answered;
	a field of an enclosing type will not be found using this API.

	If no visible field is discovered, an error binding is answered.
*/

public FieldBinding getFieldForCodeSnippet(TypeBinding receiverType, char[] fieldName, InvocationSite invocationSite) {
	FieldBinding field = findFieldForCodeSnippet(receiverType, fieldName, invocationSite);
	if (field == null)
		return new ProblemFieldBinding(receiverType instanceof ReferenceBinding ? (ReferenceBinding) receiverType : null, fieldName, ProblemReasons.NotFound);
	else
		return field;
}
/* API

	Answer the method binding that corresponds to selector, argumentTypes.
	Start the lookup at the enclosing type of the receiver.
	InvocationSite implements 
		isSuperAccess(); this is used to determine if the discovered method is visible.
		setDepth(int); this is used to record the depth of the discovered method
			relative to the enclosing type of the receiver. (If the method is defined
			in the enclosing type of the receiver, the depth is 0; in the next enclosing
			type, the depth is 1; and so on

	If no visible method is discovered, an error binding is answered.
*/

public MethodBinding getImplicitMethod(ReferenceBinding receiverType, char[] selector, TypeBinding[] argumentTypes, InvocationSite invocationSite) {
	boolean insideStaticContext = false;
	boolean insideConstructorCall = false;
	MethodBinding foundMethod = null;
	ProblemMethodBinding foundFuzzyProblem = null; // the weird method lookup case (matches method name in scope, then arg types, then visibility)
	ProblemMethodBinding foundInsideProblem = null; // inside Constructor call or inside static context
	Scope scope = this;
	boolean isExactMatch = true;
	// retrieve an exact visible match (if possible)
	MethodBinding methodBinding =
		(foundMethod == null)
			? findExactMethod(receiverType, selector, argumentTypes, invocationSite)
			: findExactMethod(receiverType, foundMethod.selector, foundMethod.parameters, invocationSite);
//						? findExactMethod(receiverType, selector, argumentTypes, invocationSite)
//						: findExactMethod(receiverType, foundMethod.selector, foundMethod.parameters, invocationSite);
	if (methodBinding == null && foundMethod == null) {
		// answers closest approximation, may not check argumentTypes or visibility
		isExactMatch = false;
		methodBinding = findMethod(receiverType, selector, argumentTypes, invocationSite);
//					methodBinding = findMethod(receiverType, selector, argumentTypes, invocationSite);
	}
	if (methodBinding != null) { // skip it if we did not find anything
		if (methodBinding.problemId() == ProblemReasons.Ambiguous) {
			if (foundMethod == null || foundMethod.problemId() == ProblemReasons.NotVisible)
				// supercedes any potential InheritedNameHidesEnclosingName problem
				return methodBinding;
			else
				// make the user qualify the method, likely wants the first inherited method (javac generates an ambiguous error instead)
				return new ProblemMethodBinding(selector, methodBinding.parameters, ProblemReasons.InheritedNameHidesEnclosingName);
		}

		ProblemMethodBinding fuzzyProblem = null;
		ProblemMethodBinding insideProblem = null;
		if (methodBinding.isValidBinding()) {
			if (!isExactMatch) {
	    	    MethodBinding compatibleMethod = computeCompatibleMethod(methodBinding, argumentTypes, invocationSite);
				if (compatibleMethod == null) {
					fuzzyProblem = new ProblemMethodBinding(methodBinding, selector, argumentTypes, ProblemReasons.NotFound);
				} else {
				    methodBinding = compatibleMethod;
				    if (!canBeSeenByForCodeSnippet(methodBinding, receiverType, invocationSite, this)) {	
						// using <classScope> instead of <this> for visibility check does grant all access to innerclass
						fuzzyProblem = new ProblemMethodBinding(methodBinding, selector, argumentTypes, ProblemReasons.NotVisible);
				    }
				}
			}
			if (fuzzyProblem == null && !methodBinding.isStatic()) {
				if (insideConstructorCall) {
					insideProblem = new ProblemMethodBinding(methodBinding, methodBinding.selector, methodBinding.parameters, ProblemReasons.NonStaticReferenceInConstructorInvocation);
				} else if (insideStaticContext) {
					insideProblem = new ProblemMethodBinding(methodBinding, methodBinding.selector, methodBinding.parameters, ProblemReasons.NonStaticReferenceInStaticContext);
				}
			}
			if (receiverType == methodBinding.declaringClass || (receiverType.getMethods(selector)) != NoMethods) {
				// found a valid method in the 'immediate' scope (ie. not inherited)
				// OR the receiverType implemented a method with the correct name
				if (foundMethod == null) {
					// return the methodBinding if it is not declared in a superclass of the scope's binding (it is inherited)
					if (fuzzyProblem != null)
						return fuzzyProblem;
					if (insideProblem != null)
						return insideProblem;
					return methodBinding;
				}
				// if a method was found, complain when another is found in an 'immediate' enclosing type (ie. not inherited)
				// NOTE: Unlike fields, a non visible method hides a visible method
				if (foundMethod.declaringClass != methodBinding.declaringClass) // ie. have we found the same method - do not trust field identity yet
					return new ProblemMethodBinding(methodBinding, methodBinding.selector, methodBinding.parameters, ProblemReasons.InheritedNameHidesEnclosingName);
			}
		}

		if (foundMethod == null || (foundMethod.problemId() == ProblemReasons.NotVisible && methodBinding.problemId() != ProblemReasons.NotVisible)) {
			// only remember the methodBinding if its the first one found or the previous one was not visible & methodBinding is...
			// remember that private methods are visible if defined directly by an enclosing class
			foundFuzzyProblem = fuzzyProblem;
			foundInsideProblem = insideProblem;
			if (fuzzyProblem == null)
				foundMethod = methodBinding; // only keep it if no error was found
		}
	}
	insideStaticContext |= receiverType.isStatic();
	// 1EX5I8Z - accessing outer fields within a constructor call is permitted
	// in order to do so, we change the flag as we exit from the type, not the method
	// itself, because the class scope is used to retrieve the fields.
	MethodScope enclosingMethodScope = scope.methodScope();
	insideConstructorCall = enclosingMethodScope == null ? false : enclosingMethodScope.isConstructorCall;

	if (foundFuzzyProblem != null)
		return foundFuzzyProblem;
	if (foundInsideProblem != null)
		return foundInsideProblem;
	if (foundMethod != null)
		return foundMethod;
	return new ProblemMethodBinding(selector, argumentTypes, ProblemReasons.NotFound);
}
}
