/*******************************************************************************
 * Copyright (c) 2000, 2010 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.codeassist;

import java.util.ArrayList;
import java.util.Locale;
import java.util.Map;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.jdt.core.CompletionContext;
import org.eclipse.jdt.core.CompletionFlags;
import org.eclipse.jdt.core.CompletionProposal;
import org.eclipse.jdt.core.CompletionRequestor;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IAccessRule;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeRoot;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.WorkingCopyOwner;
import org.eclipse.jdt.core.compiler.CategorizedProblem;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.core.search.IJavaSearchConstants;

import org.eclipse.jdt.internal.codeassist.complete.*;
import org.eclipse.jdt.internal.codeassist.impl.AssistParser;
import org.eclipse.jdt.internal.codeassist.impl.Engine;
import org.eclipse.jdt.internal.codeassist.impl.Keywords;
import org.eclipse.jdt.internal.compiler.CompilationResult;
import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
import org.eclipse.jdt.internal.compiler.ExtraFlags;
import org.eclipse.jdt.internal.compiler.ast.*;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.env.*;
import org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
import org.eclipse.jdt.internal.compiler.lookup.*;
import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
import org.eclipse.jdt.internal.compiler.parser.SourceTypeConverter;
import org.eclipse.jdt.internal.compiler.parser.JavadocTagConstants;
import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
import org.eclipse.jdt.internal.compiler.util.ObjectVector;
import org.eclipse.jdt.internal.core.BasicCompilationUnit;
import org.eclipse.jdt.internal.core.INamingRequestor;
import org.eclipse.jdt.internal.core.InternalNamingConventions;
import org.eclipse.jdt.internal.core.JavaModelManager;
import org.eclipse.jdt.internal.core.SourceMethod;
import org.eclipse.jdt.internal.core.SourceMethodElementInfo;
import org.eclipse.jdt.internal.core.SourceType;
import org.eclipse.jdt.internal.core.BinaryTypeConverter;
import org.eclipse.jdt.internal.core.SearchableEnvironment;
import org.eclipse.jdt.internal.core.SourceTypeElementInfo;
import org.eclipse.jdt.internal.core.search.matching.JavaSearchNameEnvironment;
import org.eclipse.jdt.internal.core.util.Messages;

/**
 * This class is the entry point for source completions.
 * It contains two public APIs used to call CodeAssist on a given source with
 * a given environment, assisting position and storage (and possibly options).
 */
public final class CompletionEngine
	extends Engine
	implements ISearchRequestor, TypeConstants , TerminalTokens , RelevanceConstants, SuffixConstants {
	
	private static class AcceptedConstructor {
		public int modifiers;
		public char[] simpleTypeName;
		public int parameterCount;
		public char[] signature;
		public char[][] parameterTypes;
		public char[][] parameterNames;
		public int typeModifiers;
		public char[] packageName;
		public int extraFlags;
		public int accessibility;
		public boolean proposeType = false;
		public boolean proposeConstructor = false;
		public char[] fullyQualifiedName = null;
		
		public boolean mustBeQualified = false;
		
		public AcceptedConstructor(
				int modifiers,
				char[] simpleTypeName,
				int parameterCount,
				char[] signature,
				char[][] parameterTypes,
				char[][] parameterNames,
				int typeModifiers,
				char[] packageName,
				int extraFlags,
				int accessibility) {
			this.modifiers = modifiers;
			this.simpleTypeName = simpleTypeName;
			this.parameterCount = parameterCount;
			this.signature = signature;
			this.parameterTypes = parameterTypes;
			this.parameterNames = parameterNames;
			this.typeModifiers = typeModifiers;
			this.packageName = packageName;
			this.extraFlags = extraFlags;
			this.accessibility = accessibility;
		}

		public String toString() {
			StringBuffer buffer = new StringBuffer();
			buffer.append('{');
			buffer.append(this.packageName);
			buffer.append(',');
			buffer.append(this.simpleTypeName);
			buffer.append('}');
			return buffer.toString();
		}
	}
	
	private static class AcceptedType {
		public char[] packageName;
		public char[] simpleTypeName;
		public char[][] enclosingTypeNames;
		public int modifiers;
		public int accessibility;
		public boolean mustBeQualified = false;

		public char[] fullyQualifiedName = null;
		public char[] qualifiedTypeName = null;
		public AcceptedType(
			char[] packageName,
			char[] simpleTypeName,
			char[][] enclosingTypeNames,
			int modifiers,
			int accessibility) {
			this.packageName = packageName;
			this.simpleTypeName = simpleTypeName;
			this.enclosingTypeNames = enclosingTypeNames;
			this.modifiers = modifiers;
			this.accessibility = accessibility;
		}

		public String toString() {
			StringBuffer buffer = new StringBuffer();
			buffer.append('{');
			buffer.append(this.packageName);
			buffer.append(',');
			buffer.append(this.simpleTypeName);
			buffer.append(',');
			buffer.append(CharOperation.concatWith(this.enclosingTypeNames, '.'));
			buffer.append('}');
			return buffer.toString();
		}
	}
	
	public class CompletionProblemFactory extends DefaultProblemFactory {
		private int lastErrorStart;

		private boolean checkProblems = false;
		public boolean hasForbiddenProblems = false;
		public boolean hasAllowedProblems = false;

		public CompletionProblemFactory(Locale loc) {
			super(loc);
		}

		private CategorizedProblem checkProblem(CategorizedProblem pb,
			char[] originatingFileName,	int severity, int start) {
			int id = pb.getID();
			if (CompletionEngine.this.actualCompletionPosition > start
				&& this.lastErrorStart < start
				&& pb.isError()
				&& (id & IProblem.Syntax) == 0
				&& (CompletionEngine.this.fileName == null || CharOperation.equals(CompletionEngine.this.fileName, originatingFileName))) {

				CompletionEngine.this.problem = pb;
				this.lastErrorStart = start;
			}
			if (this.checkProblems && !this.hasForbiddenProblems) {
				switch (id) {
					case IProblem.UsingDeprecatedType:
						this.hasForbiddenProblems =
							CompletionEngine.this.options.checkDeprecation;
						break;
					case IProblem.NotVisibleType:
						this.hasForbiddenProblems =
							CompletionEngine.this.options.checkVisibility;
						break;
					case IProblem.ForbiddenReference:
						this.hasForbiddenProblems =
							CompletionEngine.this.options.checkForbiddenReference;
						break;
					case IProblem.DiscouragedReference:
						this.hasForbiddenProblems =
							CompletionEngine.this.options.checkDiscouragedReference;
						break;
					default:
						if ((severity & ProblemSeverities.Optional) != 0) {
							this.hasAllowedProblems = true;
						} else {
							this.hasForbiddenProblems = true;
						}

						break;
				}
			}

			return pb;
		}

		public CategorizedProblem createProblem(
				char[] originatingFileName,
				int problemId,
				String[] problemArguments,
				int elaborationId,
				String[] messageArguments,
				int severity,
				int start,
				int end,
				int lineNumber,
				int columnNumber) {
				return checkProblem(
					super.createProblem(
						originatingFileName,
						problemId,
						problemArguments,
						elaborationId,
						messageArguments,
						severity,
						start,
						end,
						lineNumber,
						columnNumber), originatingFileName, severity, start);
		}

		public CategorizedProblem createProblem(
				char[] originatingFileName,
				int problemId,
				String[] problemArguments,
				String[] messageArguments,
				int severity,
				int start,
				int end,
				int lineNumber,
				int columnNumber) {
				return checkProblem(
					super.createProblem(
						originatingFileName,
						problemId,
						problemArguments,
						messageArguments,
						severity,
						start,
						end,
						lineNumber,
						columnNumber), originatingFileName, severity, start);
		}

		public void startCheckingProblems() {
			this.checkProblems = true;
			this.hasForbiddenProblems = false;
			this.hasAllowedProblems = false;
		}

		public void stopCheckingProblems() {
			this.checkProblems = false;
		}
	}
	
	public static char[] createBindingKey(char[] packageName, char[] typeName) {
		char[] signature = createTypeSignature(packageName, typeName);
		CharOperation.replace(signature, '.', '/');
		return signature;
	}

	public static char[][] createDefaultParameterNames(int length) {
		char[][] parameters;
		switch (length) {
			case 0 :
				parameters = new char[length][];
				break;
			case 1 :
				parameters = ARGS1;
				break;
			case 2 :
				parameters = ARGS2;
				break;
			case 3 :
				parameters = ARGS3;
				break;
			case 4 :
				parameters = ARGS4;
				break;
			default :
				parameters = new char[length][];
				for (int i = 0; i < length; i++) {
					parameters[i] = CharOperation.concat(ARG, String.valueOf(i).toCharArray());
				}
				break;
		}
		return parameters;
	}
	public static char[] createMethodSignature(char[][] parameterPackageNames, char[][] parameterTypeNames, char[] returnTypeSignature) {
		char[][] parameterTypeSignature = new char[parameterTypeNames.length][];
		for (int i = 0; i < parameterTypeSignature.length; i++) {
			parameterTypeSignature[i] =
				Signature.createCharArrayTypeSignature(
						CharOperation.concat(
								parameterPackageNames[i],
								CharOperation.replaceOnCopy(parameterTypeNames[i], '.', '$'), '.'), true);
		}

		return Signature.createMethodSignature(
				parameterTypeSignature,
				returnTypeSignature);
	}

	public static char[] createMethodSignature(char[][] parameterPackageNames, char[][] parameterTypeNames, char[] returnPackagename, char[] returnTypeName) {
		char[] returnTypeSignature =
			returnTypeName == null || returnTypeName.length == 0
			? Signature.createCharArrayTypeSignature(VOID, true)
			: Signature.createCharArrayTypeSignature(
					CharOperation.concat(
							returnPackagename,
							CharOperation.replaceOnCopy(returnTypeName, '.', '$'), '.'), true);

		return createMethodSignature(
				parameterPackageNames,
				parameterTypeNames,
				returnTypeSignature);
	}
	public static char[] createNonGenericTypeSignature(char[] qualifiedPackageName, char[] qualifiedTypeName) {
		return Signature.createCharArrayTypeSignature(
				CharOperation.concat(
						qualifiedPackageName,
						CharOperation.replaceOnCopy(qualifiedTypeName, '.', '$'), '.'), true);
	}

	public static char[] createTypeSignature(char[] qualifiedPackageName, char[] qualifiedTypeName) {
		char[] name = new char[qualifiedTypeName.length];
		System.arraycopy(qualifiedTypeName, 0, name, 0, qualifiedTypeName.length);

		int depth = 0;
		int length = name.length;
		for (int i = length -1; i >= 0; i--) {
			switch (name[i]) {
				case '.':
					if (depth == 0 && name[i - 1] != '>') {
						name[i] = '$';
					}
					break;
				case '<':
					depth--;
					break;
				case '>':
					depth++;
					break;
			}
		}
		return Signature.createCharArrayTypeSignature(
				CharOperation.concat(
						qualifiedPackageName,
						name, '.'), true);
	}

	private static char[] getRequiredTypeSignature(TypeBinding typeBinding) {
		char[] result = null;
		StringBuffer sig = new StringBuffer(10);

		sig.append(typeBinding.signature());

		int sigLength = sig.length();
		result = new char[sigLength];
		sig.getChars(0, sigLength, result, 0);
		result = CharOperation.replaceOnCopy(result, '/', '.');
		return result;
	}
	
	private static char[] getTypeName(TypeReference typeReference) {
		char[] typeName = CharOperation.concatWith(typeReference.getTypeName(), '.');
		int dims = typeReference.dimensions();
		if (dims > 0) {
			int length = typeName.length;
			int newLength = length + (dims*2);
			System.arraycopy(typeName, 0, typeName = new char[newLength], 0, length);
			for (int k = length; k < newLength; k += 2) {
				typeName[k] = '[';
				typeName[k+1] = ']';
			}
		}
		
		return typeName;
	}
	
	private static boolean hasStaticMemberTypes(ReferenceBinding typeBinding, SourceTypeBinding invocationType, CompilationUnitScope unitScope) {
		ReferenceBinding[] memberTypes = typeBinding.memberTypes();
		int length = memberTypes == null ? 0 : memberTypes.length;
		next : for (int i = 0; i < length; i++) {
			ReferenceBinding memberType = memberTypes[i];
			if (invocationType != null && !memberType.canBeSeenBy(typeBinding, invocationType)) {
				continue next;
			} else if(invocationType == null && !memberType.canBeSeenBy(unitScope.fPackage)) {
				continue next;
			}
			
			if ((memberType.modifiers & ClassFileConstants.AccStatic) != 0) {
				return true;
			}
		}
		return false;
	}
	
	private static boolean hasMemberTypesInEnclosingScope(SourceTypeBinding typeBinding, Scope scope) {
		ReferenceBinding[] memberTypes = typeBinding.memberTypes();
		int length = memberTypes == null ? 0 : memberTypes.length;
		
		if (length > 0) {
			MethodScope methodScope = scope.methodScope();
			if (methodScope != null && !methodScope.isStatic) {
				ClassScope classScope = typeBinding.scope;
				Scope currentScope = scope;
				while (currentScope != null) {
					if (currentScope == classScope) {
						return true;
					}
					currentScope = currentScope.parent;
				}
			}
		}
		return false;
	}
	
	public HashtableOfObject typeCache;
	public int openedBinaryTypes; // used during InternalCompletionProposal#findConstructorParameterNames()
	
	public static boolean DEBUG = false;
	public static boolean PERF = false;
	
	private static final char[] KNOWN_TYPE_WITH_UNKNOWN_CONSTRUCTORS = new char[]{};
	private static final char[] KNOWN_TYPE_WITH_KNOWN_CONSTRUCTORS = new char[]{};
	
	private static final char[] ARG = "arg".toCharArray();  //$NON-NLS-1$
	private static final char[] ARG0 = "arg0".toCharArray();  //$NON-NLS-1$
	private static final char[] ARG1 = "arg1".toCharArray();  //$NON-NLS-1$
	private static final char[] ARG2 = "arg2".toCharArray();  //$NON-NLS-1$
	private static final char[] ARG3 = "arg3".toCharArray();  //$NON-NLS-1$
	private static final char[][] ARGS1 = new char[][]{ARG0};
	private static final char[][] ARGS2 = new char[][]{ARG0, ARG1};
	private static final char[][] ARGS3 = new char[][]{ARG0, ARG1, ARG2};
	private static final char[][] ARGS4 = new char[][]{ARG0, ARG1, ARG2, ARG3};
	
	private final static int CHECK_CANCEL_FREQUENCY = 50;
	
	// temporary constants to quickly disabled polish features if necessary
	public final static boolean NO_TYPE_COMPLETION_ON_EMPTY_TOKEN = false;
	
	private final static char[] ERROR_PATTERN = "*error*".toCharArray();  //$NON-NLS-1$
	private final static char[] EXCEPTION_PATTERN = "*exception*".toCharArray();  //$NON-NLS-1$
	private final static char[] SEMICOLON = new char[] { ';' };

	private final static char[] CLASS = "Class".toCharArray();  //$NON-NLS-1$
	private final static char[] VOID = "void".toCharArray();  //$NON-NLS-1$
	private final static char[] INT = "int".toCharArray();  //$NON-NLS-1$
	private final static char[] INT_SIGNATURE = new char[]{Signature.C_INT};
	private final static char[] VALUE = "value".toCharArray();  //$NON-NLS-1$
	private final static char[] EXTENDS = "extends".toCharArray();  //$NON-NLS-1$
	private final static char[] SUPER = "super".toCharArray();  //$NON-NLS-1$
	private final static char[] DEFAULT_CONSTRUCTOR_SIGNATURE = "()V".toCharArray();  //$NON-NLS-1$
	
	private final static char[] DOT = ".".toCharArray();  //$NON-NLS-1$

	private final static char[] VARARGS = "...".toCharArray();  //$NON-NLS-1$
	
	private final static char[] IMPORT = "import".toCharArray();  //$NON-NLS-1$
	private final static char[] STATIC = "static".toCharArray();  //$NON-NLS-1$
	private final static char[] ON_DEMAND = ".*".toCharArray();  //$NON-NLS-1$
	private final static char[] IMPORT_END = ";\n".toCharArray();  //$NON-NLS-1$

	private final static char[] JAVA_LANG_OBJECT_SIGNATURE =
		createTypeSignature(CharOperation.concatWith(JAVA_LANG, '.'), OBJECT);
	private final static char[] JAVA_LANG_NAME =
		CharOperation.concatWith(JAVA_LANG, '.');
	
	private final static int NONE = 0;
	private final static int SUPERTYPE = 1;
	private final static int SUBTYPE = 2;
	
	int expectedTypesPtr = -1;
	TypeBinding[] expectedTypes = new TypeBinding[1];
	int expectedTypesFilter;
	boolean hasJavaLangObjectAsExpectedType = false;
	boolean hasExpectedArrayTypes = false;
	boolean hasComputedExpectedArrayTypes = false;
	int uninterestingBindingsPtr = -1;
	Binding[] uninterestingBindings = new Binding[1];
	int forbbidenBindingsPtr = -1;
	Binding[] forbbidenBindings = new Binding[1];
	int forbbidenBindingsFilter;
	
	ImportBinding[] favoriteReferenceBindings;
	
	boolean assistNodeIsClass;
	boolean assistNodeIsEnum;
	boolean assistNodeIsException;
	boolean assistNodeIsInterface;
	boolean assistNodeIsAnnotation;
	boolean assistNodeIsConstructor;
	boolean assistNodeIsSuperType;
	boolean assistNodeIsExtendedType;
	boolean assistNodeIsInterfaceExcludingAnnotation; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=310423
	int  assistNodeInJavadoc = 0;
	boolean assistNodeCanBeSingleMemberAnnotation = false;
	boolean assistNodeIsInsideCase = false; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=195346
	
	long targetedElement;
	
	WorkingCopyOwner owner;
	IProgressMonitor monitor;
	IJavaProject javaProject;
	ITypeRoot typeRoot;
	CompletionParser parser;
	CompletionRequestor requestor;
	CompletionProblemFactory problemFactory;
	ProblemReporter problemReporter;
	private JavaSearchNameEnvironment noCacheNameEnvironment;
	char[] source;
	char[] completionToken;
	char[] qualifiedCompletionToken;
	boolean resolvingImports = false;
	boolean resolvingStaticImports = false;
	boolean insideQualifiedReference = false;
	boolean noProposal = true;
	CategorizedProblem problem = null;
	char[] fileName = null;
	int startPosition, actualCompletionPosition, endPosition, offset;
	int tokenStart, tokenEnd;
	int javadocTagPosition; // Position of previous tag while completing in javadoc
	HashtableOfObject knownPkgs = new HashtableOfObject(10);
	HashtableOfObject knownTypes = new HashtableOfObject(10);
	
 	/*
		static final char[][] mainDeclarations =
			new char[][] {
				"package".toCharArray(),
				"import".toCharArray(),
				"abstract".toCharArray(),
				"final".toCharArray(),
				"public".toCharArray(),
				"class".toCharArray(),
				"interface".toCharArray()};

		static final char[][] modifiers = // may want field, method, type & member type modifiers
			new char[][] {
				"abstract".toCharArray(),
				"final".toCharArray(),
				"native".toCharArray(),
				"public".toCharArray(),
				"protected".toCharArray(),
				"private".toCharArray(),
				"static".toCharArray(),
				"strictfp".toCharArray(),
				"synchronized".toCharArray(),
				"transient".toCharArray(),
				"volatile".toCharArray()};
	*/
	static final BaseTypeBinding[] BASE_TYPES = {
		TypeBinding.BOOLEAN,
		TypeBinding.BYTE,
		TypeBinding.CHAR,
		TypeBinding.DOUBLE,
		TypeBinding.FLOAT,
		TypeBinding.INT,
		TypeBinding.LONG,
		TypeBinding.SHORT,
		TypeBinding.VOID
	};
	static final int BASE_TYPES_LENGTH = BASE_TYPES.length;
	static final char[][] BASE_TYPE_NAMES = new char[BASE_TYPES_LENGTH][];
	static final int BASE_TYPES_WITHOUT_VOID_LENGTH = BASE_TYPES.length - 1;
	static final char[][] BASE_TYPE_NAMES_WITHOUT_VOID = new char[BASE_TYPES_WITHOUT_VOID_LENGTH][];
	static {
 		for (int i=0; i<BASE_TYPES_LENGTH; i++) {
 			BASE_TYPE_NAMES[i] = BASE_TYPES[i].simpleName;
 		}
		for (int i=0; i<BASE_TYPES_WITHOUT_VOID_LENGTH; i++) {
			BASE_TYPE_NAMES_WITHOUT_VOID[i] = BASE_TYPES[i].simpleName;
		}
 	}
	
	static final char[] classField = "class".toCharArray();  //$NON-NLS-1$
	static final char[] lengthField = "length".toCharArray();  //$NON-NLS-1$
	static final char[] cloneMethod = "clone".toCharArray();  //$NON-NLS-1$
	static final char[] THIS = "this".toCharArray();  //$NON-NLS-1$
	static final char[] THROWS = "throws".toCharArray();  //$NON-NLS-1$

	static InvocationSite FakeInvocationSite = new InvocationSite(){
		public TypeBinding[] genericTypeArguments() { return null; }
		public boolean isSuperAccess(){ return false; }
		public boolean isTypeAccess(){ return false; }
		public void setActualReceiverType(ReferenceBinding receiverType) {/* empty */}
		public void setDepth(int depth){/* empty */}
		public void setFieldIndex(int depth){/* empty */}
		public int sourceEnd() { return 0; 	}
		public int sourceStart() { return 0; 	}
		public TypeBinding expectedType() { return null; }
	};

	private int foundTypesCount;
	private ObjectVector acceptedTypes;
	
	private int foundConstructorsCount;
	private ObjectVector acceptedConstructors;

	/**
	 * The CompletionEngine is responsible for computing source completions.
	 *
	 * It requires a searchable name environment, which supports some
	 * specific search APIs, and a requestor to feed back the results to a UI.
	 *
	 *  @param nameEnvironment org.eclipse.jdt.internal.codeassist.ISearchableNameEnvironment
	 *      used to resolve type/package references and search for types/packages
	 *      based on partial names.
	 *
	 *  @param requestor org.eclipse.jdt.internal.codeassist.ICompletionRequestor
	 *      since the engine might produce answers of various forms, the engine
	 *      is associated with a requestor able to accept all possible completions.
	 *
	 *  @param settings java.util.Map
	 *		set of options used to configure the code assist engine.
	 */
	public CompletionEngine(
			SearchableEnvironment nameEnvironment,
			CompletionRequestor requestor,
			Map settings,
			IJavaProject javaProject,
			WorkingCopyOwner owner,
			IProgressMonitor monitor) {
		super(settings);
		this.javaProject = javaProject;
		this.requestor = requestor;
		this.nameEnvironment = nameEnvironment;
		this.typeCache = new HashtableOfObject(5);
		this.openedBinaryTypes = 0;

		this.problemFactory = new CompletionProblemFactory(Locale.getDefault());
		this.problemReporter = new ProblemReporter(
				DefaultErrorHandlingPolicies.proceedWithAllProblems(),
				this.compilerOptions,
				this.problemFactory);
		this.lookupEnvironment =
			new LookupEnvironment(this, this.compilerOptions, this.problemReporter, nameEnvironment);
		this.parser =
			new CompletionParser(this.problemReporter, this.requestor.isExtendedContextRequired());
		this.owner = owner;
		this.monitor = monitor;
	}
	
	public void acceptConstructor(
			int modifiers,
			char[] simpleTypeName,
			int parameterCount,
			char[] signature,
			char[][] parameterTypes,
			char[][] parameterNames,
			int typeModifiers,
			char[] packageName,
			int extraFlags,
			String path,
			AccessRestriction accessRestriction) {
		
		// does not check cancellation for every types to avoid performance loss
		if ((this.foundConstructorsCount % (CHECK_CANCEL_FREQUENCY)) == 0) checkCancel();
		this.foundConstructorsCount++;
		
		if ((typeModifiers & ClassFileConstants.AccEnum) != 0) return;
		
		if (this.options.checkDeprecation && (typeModifiers & ClassFileConstants.AccDeprecated) != 0) return;

		if (this.options.checkVisibility) {
			if((typeModifiers & ClassFileConstants.AccPublic) == 0) {
				if((typeModifiers & ClassFileConstants.AccPrivate) != 0) return;

				if (this.currentPackageName == null) {
					initializePackageCache();
				}
				
				if(!CharOperation.equals(packageName, this.currentPackageName)) return;
			}
		}

		int accessibility = IAccessRule.K_ACCESSIBLE;
		if(accessRestriction != null) {
			switch (accessRestriction.getProblemId()) {
				case IProblem.ForbiddenReference:
					if (this.options.checkForbiddenReference) {
						return;
					}
					accessibility = IAccessRule.K_NON_ACCESSIBLE;
					break;
				case IProblem.DiscouragedReference:
					if (this.options.checkDiscouragedReference) {
						return;
					}
					accessibility = IAccessRule.K_DISCOURAGED;
					break;
			}
		}
		
		if(this.acceptedConstructors == null) {
			this.acceptedConstructors = new ObjectVector();
		}
		this.acceptedConstructors.add(
				new AcceptedConstructor(
						modifiers,
						simpleTypeName,
						parameterCount,
						signature,
						parameterTypes,
						parameterNames,
						typeModifiers,
						packageName,
						extraFlags,
						accessibility));
	}
	
	private void acceptConstructors(Scope scope) {
		final boolean DEFER_QUALIFIED_PROPOSALS = false;
		
		this.checkCancel();
		
		if(this.acceptedConstructors == null) return;

		int length = this.acceptedConstructors.size();

		if(length == 0) return;
		
		HashtableOfObject onDemandFound = new HashtableOfObject();
		
		ArrayList deferredProposals = null;
		if (DEFER_QUALIFIED_PROPOSALS) {
			deferredProposals = new ArrayList();
		}
		
		try {
			next : for (int i = 0; i < length; i++) {
				
				// does not check cancellation for every types to avoid performance loss
				if ((i % CHECK_CANCEL_FREQUENCY) == 0) checkCancel();
				
				AcceptedConstructor acceptedConstructor = (AcceptedConstructor)this.acceptedConstructors.elementAt(i);
				final int typeModifiers = acceptedConstructor.typeModifiers;
				final char[] packageName = acceptedConstructor.packageName;
				final char[] simpleTypeName = acceptedConstructor.simpleTypeName;
				final int modifiers = acceptedConstructor.modifiers;
				final int parameterCount = acceptedConstructor.parameterCount;
				final char[] signature = acceptedConstructor.signature;
				final char[][] parameterTypes = acceptedConstructor.parameterTypes;
				final char[][] parameterNames = acceptedConstructor.parameterNames;
				final int extraFlags = acceptedConstructor.extraFlags;
				final int accessibility = acceptedConstructor.accessibility;
				
				boolean proposeType = hasArrayTypeAsExpectedSuperTypes() || (extraFlags & ExtraFlags.HasNonPrivateStaticMemberTypes) != 0;
				
				char[] fullyQualifiedName = CharOperation.concat(packageName, simpleTypeName, '.');
						
				Object knownTypeKind = this.knownTypes.get(fullyQualifiedName);
				if (knownTypeKind != null) {
					if (knownTypeKind == KNOWN_TYPE_WITH_KNOWN_CONSTRUCTORS) {
						// the type and its constructors are already accepted
						continue next;
					}
					// this type is already accepted
					proposeType = false;
				} else {
					this.knownTypes.put(fullyQualifiedName, KNOWN_TYPE_WITH_UNKNOWN_CONSTRUCTORS);
				}
				
				boolean proposeConstructor = true;
					
				if (this.options.checkVisibility) {
					if((modifiers & ClassFileConstants.AccPublic) == 0) {
						if((modifiers & ClassFileConstants.AccPrivate) != 0) {
							if (!proposeType) continue next;
							proposeConstructor = false;
						} else {
							if (this.currentPackageName == null) {
								initializePackageCache();
							}
							
							if(!CharOperation.equals(packageName, this.currentPackageName)) {
								
								if((typeModifiers & ClassFileConstants.AccAbstract) == 0 ||
										(modifiers & ClassFileConstants.AccProtected) == 0) {
									if (!proposeType) continue next;
									proposeConstructor = false;
								}
							}
						}
					}
				}
				
				acceptedConstructor.fullyQualifiedName = fullyQualifiedName;
				acceptedConstructor.proposeType = proposeType;
				acceptedConstructor.proposeConstructor = proposeConstructor;
				
				
				if(!this.importCachesInitialized) {
					initializeImportCaches();
				}
				
				for (int j = 0; j < this.importCacheCount; j++) {
					char[][] importName = this.importsCache[j];
					if(CharOperation.equals(simpleTypeName, importName[0])) {
						if (proposeType) {
							proposeType(
									packageName,
									simpleTypeName,
									typeModifiers,
									accessibility,
									simpleTypeName,
									fullyQualifiedName,
									!CharOperation.equals(fullyQualifiedName, importName[1]),
									scope);
						}
						
						if (proposeConstructor && !Flags.isEnum(typeModifiers)) {
							boolean isQualified = !CharOperation.equals(fullyQualifiedName, importName[1]);
							if (!isQualified) {
								proposeConstructor(
										simpleTypeName,
										parameterCount,
										signature,
										parameterTypes,
										parameterNames,
										modifiers,
										packageName,
										typeModifiers,
										accessibility,
										simpleTypeName,
										fullyQualifiedName,
										isQualified,
										scope,
										extraFlags);
							} else {
								acceptedConstructor.mustBeQualified = true;
								if (DEFER_QUALIFIED_PROPOSALS) {
									deferredProposals.add(acceptedConstructor);
								} else {
									proposeConstructor(acceptedConstructor, scope);
								}
							}
						}
						continue next;
					}
				}


				if (CharOperation.equals(this.currentPackageName, packageName)) {
					if (proposeType) {
						proposeType(
								packageName,
								simpleTypeName,
								typeModifiers,
								accessibility,
								simpleTypeName,
								fullyQualifiedName,
								false,
								scope);
					}
					
					if (proposeConstructor && !Flags.isEnum(typeModifiers)) {
						proposeConstructor(
								simpleTypeName,
								parameterCount,
								signature,
								parameterTypes,
								parameterNames,
								modifiers,
								packageName,
								typeModifiers,
								accessibility,
								simpleTypeName,
								fullyQualifiedName,
								false,
								scope,
								extraFlags);
					}
					continue next;
				} else {
					char[] fullyQualifiedEnclosingTypeOrPackageName = null;

					AcceptedConstructor foundConstructor = null;
					if((foundConstructor = (AcceptedConstructor)onDemandFound.get(simpleTypeName)) == null) {
						for (int j = 0; j < this.onDemandImportCacheCount; j++) {
							ImportBinding importBinding = this.onDemandImportsCache[j];

							char[][] importName = importBinding.compoundName;
							char[] importFlatName = CharOperation.concatWith(importName, '.');

							if(fullyQualifiedEnclosingTypeOrPackageName == null) {
								fullyQualifiedEnclosingTypeOrPackageName = packageName;
							}
							if(CharOperation.equals(fullyQualifiedEnclosingTypeOrPackageName, importFlatName)) {
								if(importBinding.isStatic()) {
									if((typeModifiers & ClassFileConstants.AccStatic) != 0) {
										onDemandFound.put(
												simpleTypeName,
												acceptedConstructor);
										continue next;
									}
								} else {
									onDemandFound.put(
											simpleTypeName,
											acceptedConstructor);
									continue next;
								}
							}
						}
					} else if(!foundConstructor.mustBeQualified){
						done : for (int j = 0; j < this.onDemandImportCacheCount; j++) {
							ImportBinding importBinding = this.onDemandImportsCache[j];

							char[][] importName = importBinding.compoundName;
							char[] importFlatName = CharOperation.concatWith(importName, '.');

							if(fullyQualifiedEnclosingTypeOrPackageName == null) {
								fullyQualifiedEnclosingTypeOrPackageName = packageName;
							}
							if(CharOperation.equals(fullyQualifiedEnclosingTypeOrPackageName, importFlatName)) {
								if(importBinding.isStatic()) {
									if((typeModifiers & ClassFileConstants.AccStatic) != 0) {
										foundConstructor.mustBeQualified = true;
										break done;
									}
								} else {
									foundConstructor.mustBeQualified = true;
									break done;
								}
							}
						}
					}
					if (proposeType) {
						proposeType(
								packageName,
								simpleTypeName,
								typeModifiers,
								accessibility,
								simpleTypeName,
								fullyQualifiedName,
								true,
								scope);
					}
					
					if (proposeConstructor && !Flags.isEnum(typeModifiers)) {
						acceptedConstructor.mustBeQualified = true;
						if (DEFER_QUALIFIED_PROPOSALS) {
							deferredProposals.add(acceptedConstructor);
						} else {
							proposeConstructor(acceptedConstructor, scope);
						}
					}
				}
			}
		
			char[][] keys = onDemandFound.keyTable;
			Object[] values = onDemandFound.valueTable;
			int max = keys.length;
			for (int i = 0; i < max; i++) {
				
				// does not check cancellation for every types to avoid performance loss
				if ((i % CHECK_CANCEL_FREQUENCY) == 0) checkCancel();
				
				if(keys[i] != null) {
					AcceptedConstructor value = (AcceptedConstructor) values[i];
					if(value != null) {
						if (value.proposeType) {
							proposeType(
									value.packageName,
									value.simpleTypeName,
									value.typeModifiers,
									value.accessibility,
									value.simpleTypeName,
									value.fullyQualifiedName,
									value.mustBeQualified,
									scope);
						}
						
						if (value.proposeConstructor && !Flags.isEnum(value.modifiers)) {
							if (!value.mustBeQualified) {
								proposeConstructor(
										value.simpleTypeName,
										value.parameterCount,
										value.signature,
										value.parameterTypes,
										value.parameterNames,
										value.modifiers,
										value.packageName,
										value.typeModifiers,
										value.accessibility,
										value.simpleTypeName,
										value.fullyQualifiedName,
										value.mustBeQualified,
										scope,
										value.extraFlags);
							} else {
								if (DEFER_QUALIFIED_PROPOSALS) {
									deferredProposals.add(value);
								} else {
									proposeConstructor(value, scope);
								}
							}
						}
					}
				}
			}
			
			if (DEFER_QUALIFIED_PROPOSALS) {
				int size = deferredProposals.size();
				for (int i = 0; i < size; i++) {
					
					// does not check cancellation for every types to avoid performance loss
					if ((i % CHECK_CANCEL_FREQUENCY) == 0) checkCancel();
				
					AcceptedConstructor deferredProposal = (AcceptedConstructor)deferredProposals.get(i);
					
					if (deferredProposal.proposeConstructor) {
						proposeConstructor(
								deferredProposal.simpleTypeName,
								deferredProposal.parameterCount,
								deferredProposal.signature,
								deferredProposal.parameterTypes,
								deferredProposal.parameterNames,
								deferredProposal.modifiers,
								deferredProposal.packageName,
								deferredProposal.typeModifiers,
								deferredProposal.accessibility,
								deferredProposal.simpleTypeName,
								deferredProposal.fullyQualifiedName,
								deferredProposal.mustBeQualified,
								scope,
								deferredProposal.extraFlags);
					}
				}
			}
		} finally {
			this.acceptedTypes = null; // reset
		}
	}

	/**
	 * One result of the search consists of a new package.
	 *
	 * NOTE - All package names are presented in their readable form:
	 *    Package names are in the form "a.b.c".
	 *    The default package is represented by an empty array.
	 */
	public void acceptPackage(char[] packageName) {

		if (this.knownPkgs.containsKey(packageName)) return;

		this.knownPkgs.put(packageName, this);

		char[] completion;
		if(this.resolvingImports) {
			if(this.resolvingStaticImports) {
				completion = CharOperation.concat(packageName, new char[] { '.' });
			} else {
				completion = CharOperation.concat(packageName, new char[] { '.', '*', ';' });
			}
		} else {
			completion = packageName;
		}

		int relevance = computeBaseRelevance();
		relevance += computeRelevanceForResolution();
		relevance += computeRelevanceForInterestingProposal();
		relevance += computeRelevanceForCaseMatching(this.qualifiedCompletionToken == null ? this.completionToken : this.qualifiedCompletionToken, packageName);
		if(!this.resolvingImports) {
			relevance += computeRelevanceForQualification(true);
		}
		relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);

		this.noProposal = false;
		if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
			InternalCompletionProposal proposal = createProposal(CompletionProposal.PACKAGE_REF, this.actualCompletionPosition);
			proposal.setDeclarationSignature(packageName);
			proposal.setPackageName(packageName);
			proposal.setCompletion(completion);
			proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
			proposal.setRelevance(relevance);
			this.requestor.accept(proposal);
			if(DEBUG) {
				this.printDebug(proposal);
			}
		}
	}

	/**
	 * One result of the search consists of a new type.
	 *
	 * NOTE - All package and type names are presented in their readable form:
	 *    Package names are in the form "a.b.c".
	 *    Nested type names are in the qualified form "A.I".
	 *    The default package is represented by an empty array.
	 */
	public void acceptType(
		char[] packageName,
		char[] simpleTypeName,
		char[][] enclosingTypeNames,
		int modifiers,
		AccessRestriction accessRestriction) {
		
		// does not check cancellation for every types to avoid performance loss
		if ((this.foundTypesCount % CHECK_CANCEL_FREQUENCY) == 0) checkCancel();
		this.foundTypesCount++;
		
		if (this.options.checkDeprecation && (modifiers & ClassFileConstants.AccDeprecated) != 0) return;
		if (this.assistNodeIsExtendedType && (modifiers & ClassFileConstants.AccFinal) != 0) return;

		if (this.options.checkVisibility) {
			if((modifiers & ClassFileConstants.AccPublic) == 0) {
				if((modifiers & ClassFileConstants.AccPrivate) != 0) return;

				char[] currentPackage = CharOperation.concatWith(this.unitScope.fPackage.compoundName, '.');
				if(!CharOperation.equals(packageName, currentPackage)) return;
			}
		}

		int accessibility = IAccessRule.K_ACCESSIBLE;
		if(accessRestriction != null) {
			switch (accessRestriction.getProblemId()) {
				case IProblem.ForbiddenReference:
					if (this.options.checkForbiddenReference) {
						return;
					}
					accessibility = IAccessRule.K_NON_ACCESSIBLE;
					break;
				case IProblem.DiscouragedReference:
					if (this.options.checkDiscouragedReference) {
						return;
					}
					accessibility = IAccessRule.K_DISCOURAGED;
					break;
			}
		}
		
		if (isForbiddenType(packageName, simpleTypeName, enclosingTypeNames)) {
			return;
		}

		if(this.acceptedTypes == null) {
			this.acceptedTypes = new ObjectVector();
		}
		this.acceptedTypes.add(new AcceptedType(packageName, simpleTypeName, enclosingTypeNames, modifiers, accessibility));
	}

	private void acceptTypes(Scope scope) {
		this.checkCancel();
		
		if(this.acceptedTypes == null) return;

		int length = this.acceptedTypes.size();

		if(length == 0) return;

		HashtableOfObject onDemandFound = new HashtableOfObject();
		
		try {
			next : for (int i = 0; i < length; i++) {
				
				// does not check cancellation for every types to avoid performance loss
				if ((i % CHECK_CANCEL_FREQUENCY) == 0) checkCancel();
				
				AcceptedType acceptedType = (AcceptedType)this.acceptedTypes.elementAt(i);
				char[] packageName = acceptedType.packageName;
				char[] simpleTypeName = acceptedType.simpleTypeName;
				char[][] enclosingTypeNames = acceptedType.enclosingTypeNames;
				int modifiers = acceptedType.modifiers;
				int accessibility = acceptedType.accessibility;
	
				char[] typeName;
				char[] flatEnclosingTypeNames;
				if(enclosingTypeNames == null || enclosingTypeNames.length == 0) {
					flatEnclosingTypeNames = null;
					typeName = simpleTypeName;
				} else {
					flatEnclosingTypeNames = CharOperation.concatWith(acceptedType.enclosingTypeNames, '.');
					typeName = CharOperation.concat(flatEnclosingTypeNames, simpleTypeName, '.');
				}
				char[] fullyQualifiedName = CharOperation.concat(packageName, typeName, '.');
	
				if (this.knownTypes.containsKey(fullyQualifiedName)) continue next;
	
				this.knownTypes.put(fullyQualifiedName, KNOWN_TYPE_WITH_UNKNOWN_CONSTRUCTORS);
	
				if (this.resolvingImports) {
					if(this.compilerOptions.complianceLevel >= ClassFileConstants.JDK1_4 && packageName.length == 0) {
						continue next; // import of default package is forbidden when compliance is 1.4 or higher
					}
	
					char[] completionName = this.insideQualifiedReference ? simpleTypeName : fullyQualifiedName;
	
					if(this.resolvingStaticImports) {
						if(enclosingTypeNames == null || enclosingTypeNames.length == 0) {
							completionName = CharOperation.concat(completionName, new char[] { '.' });
						} else if ((modifiers & ClassFileConstants.AccStatic) == 0) {
							continue next;
						} else {
							completionName = CharOperation.concat(completionName, new char[] { ';' });
						}
					} else {
						completionName = CharOperation.concat(completionName, new char[] { ';' });
					}
	
					int relevance = computeBaseRelevance();
					relevance += computeRelevanceForResolution();
					relevance += computeRelevanceForInterestingProposal();
					relevance += computeRelevanceForRestrictions(accessibility);
					relevance += computeRelevanceForCaseMatching(this.completionToken, simpleTypeName);
	
					this.noProposal = false;
					if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
						createTypeProposal(packageName, typeName, modifiers, accessibility, completionName, relevance);
					}
				} else {
					if(!this.importCachesInitialized) {
						initializeImportCaches();
					}
	
					for (int j = 0; j < this.importCacheCount; j++) {
						char[][] importName = this.importsCache[j];
						if(CharOperation.equals(typeName, importName[0])) {
							proposeType(
									packageName,
									simpleTypeName,
									modifiers,
									accessibility,
									typeName,
									fullyQualifiedName,
									!CharOperation.equals(fullyQualifiedName, importName[1]),
									scope);
							continue next;
						}
					}
	
	
					if ((enclosingTypeNames == null || enclosingTypeNames.length == 0 ) && CharOperation.equals(this.currentPackageName, packageName)) {
						proposeType(
								packageName,
								simpleTypeName,
								modifiers,
								accessibility,
								typeName,
								fullyQualifiedName,
								false,
								scope);
						continue next;
					} else {
						char[] fullyQualifiedEnclosingTypeOrPackageName = null;
	
						AcceptedType foundType = null;
						if((foundType = (AcceptedType)onDemandFound.get(simpleTypeName)) == null) {
							for (int j = 0; j < this.onDemandImportCacheCount; j++) {
								ImportBinding importBinding = this.onDemandImportsCache[j];
	
								char[][] importName = importBinding.compoundName;
								char[] importFlatName = CharOperation.concatWith(importName, '.');
	
								if(fullyQualifiedEnclosingTypeOrPackageName == null) {
									if(enclosingTypeNames != null && enclosingTypeNames.length != 0) {
										fullyQualifiedEnclosingTypeOrPackageName =
											CharOperation.concat(
													packageName,
													flatEnclosingTypeNames,
													'.');
									} else {
										fullyQualifiedEnclosingTypeOrPackageName =
											packageName;
									}
								}
								if(CharOperation.equals(fullyQualifiedEnclosingTypeOrPackageName, importFlatName)) {
									if(importBinding.isStatic()) {
										if((modifiers & ClassFileConstants.AccStatic) != 0) {
											acceptedType.qualifiedTypeName = typeName;
											acceptedType.fullyQualifiedName = fullyQualifiedName;
											onDemandFound.put(
													simpleTypeName,
													acceptedType);
											continue next;
										}
									} else {
										acceptedType.qualifiedTypeName = typeName;
										acceptedType.fullyQualifiedName = fullyQualifiedName;
										onDemandFound.put(
												simpleTypeName,
												acceptedType);
										continue next;
									}
								}
							}
						} else if(!foundType.mustBeQualified){
							done : for (int j = 0; j < this.onDemandImportCacheCount; j++) {
								ImportBinding importBinding = this.onDemandImportsCache[j];
	
								char[][] importName = importBinding.compoundName;
								char[] importFlatName = CharOperation.concatWith(importName, '.');
	
								if(fullyQualifiedEnclosingTypeOrPackageName == null) {
									if(enclosingTypeNames != null && enclosingTypeNames.length != 0) {
										fullyQualifiedEnclosingTypeOrPackageName =
											CharOperation.concat(
													packageName,
													flatEnclosingTypeNames,
													'.');
									} else {
										fullyQualifiedEnclosingTypeOrPackageName =
											packageName;
									}
								}
								if(CharOperation.equals(fullyQualifiedEnclosingTypeOrPackageName, importFlatName)) {
									if(importBinding.isStatic()) {
										if((modifiers & ClassFileConstants.AccStatic) != 0) {
											foundType.mustBeQualified = true;
											break done;
										}
									} else {
										foundType.mustBeQualified = true;
										break done;
									}
								}
							}
						}
						proposeType(
								packageName,
								simpleTypeName,
								modifiers,
								accessibility,
								typeName,
								fullyQualifiedName,
								true,
								scope);
					}
				}
			}
		
			char[][] keys = onDemandFound.keyTable;
			Object[] values = onDemandFound.valueTable;
			int max = keys.length;
			for (int i = 0; i < max; i++) {
				if ((i % CHECK_CANCEL_FREQUENCY) == 0) checkCancel();
				if(keys[i] != null) {
					AcceptedType value = (AcceptedType) values[i];
					if(value != null) {
						proposeType(
								value.packageName,
								value.simpleTypeName,
								value.modifiers,
								value.accessibility,
								value.qualifiedTypeName,
								value.fullyQualifiedName,
								value.mustBeQualified,
								scope);
					}
				}
			}
		} finally {
			this.acceptedTypes = null; // reset
		}
	}
	
	public void acceptUnresolvedName(char[] name) {
		int relevance = computeBaseRelevance();
		relevance += computeRelevanceForResolution(false);
		relevance += computeRelevanceForInterestingProposal();
		relevance += computeRelevanceForCaseMatching(this.completionToken, name);
		relevance += computeRelevanceForQualification(false);
		relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for local variable
		CompletionEngine.this.noProposal = false;
		if(!CompletionEngine.this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
			InternalCompletionProposal proposal = CompletionEngine.this.createProposal(CompletionProposal.LOCAL_VARIABLE_REF, CompletionEngine.this.actualCompletionPosition);
			proposal.setSignature(JAVA_LANG_OBJECT_SIGNATURE);
			proposal.setPackageName(JAVA_LANG_NAME);
			proposal.setTypeName(OBJECT);
			proposal.setName(name);
			proposal.setCompletion(name);
			proposal.setFlags(Flags.AccDefault);
			proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
			proposal.setRelevance(relevance);
			CompletionEngine.this.requestor.accept(proposal);
			if(DEBUG) {
				CompletionEngine.this.printDebug(proposal);
			}
		}
	}
	private void addExpectedType(TypeBinding type, Scope scope){
		if (type == null || !type.isValidBinding() || type == TypeBinding.NULL) return;

		// do not add twice the same type
		for (int i = 0; i <= this.expectedTypesPtr; i++) {
			if (this.expectedTypes[i] == type) return;
		}

		int length = this.expectedTypes.length;
		if (++this.expectedTypesPtr >= length)
			System.arraycopy(this.expectedTypes, 0, this.expectedTypes = new TypeBinding[length * 2], 0, length);
		this.expectedTypes[this.expectedTypesPtr] = type;

		if(type == scope.getJavaLangObject()) {
			this.hasJavaLangObjectAsExpectedType = true;
		}
	}

	private void addForbiddenBindings(Binding binding){
		if (binding == null) return;

		int length = this.forbbidenBindings.length;
		if (++this.forbbidenBindingsPtr >= length)
			System.arraycopy(this.forbbidenBindings, 0, this.forbbidenBindings = new Binding[length * 2], 0, length);
		this.forbbidenBindings[this.forbbidenBindingsPtr] = binding;
	}

	private void addUninterestingBindings(Binding binding){
		if (binding == null) return;

		int length = this.uninterestingBindings.length;
		if (++this.uninterestingBindingsPtr >= length)
			System.arraycopy(this.uninterestingBindings, 0, this.uninterestingBindings = new Binding[length * 2], 0, length);
		this.uninterestingBindings[this.uninterestingBindingsPtr] = binding;
	}

	// this code is derived from MethodBinding#areParametersCompatibleWith(TypeBinding[])
	private final boolean areParametersCompatibleWith(TypeBinding[] parameters, TypeBinding[] arguments, boolean isVarargs) {
		int paramLength = parameters.length;
		int argLength = arguments.length;
		int lastIndex = argLength;
		if (isVarargs) {
			lastIndex = paramLength - 1;
			if (paramLength == argLength) { // accept X[] but not X or X[][]
				TypeBinding varArgType = parameters[lastIndex]; // is an ArrayBinding by definition
				TypeBinding lastArgument = arguments[lastIndex];
				if (varArgType != lastArgument && !lastArgument.isCompatibleWith(varArgType))
					return false;
			} else if (paramLength < argLength) { // all remainig argument types must be compatible with the elementsType of varArgType
				TypeBinding varArgType = ((ArrayBinding) parameters[lastIndex]).elementsType();
				for (int i = lastIndex; i < argLength; i++)
					if (varArgType != arguments[i] && !arguments[i].isCompatibleWith(varArgType))
						return false;
			} else if (lastIndex != argLength) { // can call foo(int i, X ... x) with foo(1) but NOT foo();
				return false;
			}
			// now compare standard arguments from 0 to lastIndex
		} else {
			if(paramLength != argLength)
				return false;
		}
		for (int i = 0; i < lastIndex; i++)
			if (parameters[i] != arguments[i] && !arguments[i].isCompatibleWith(parameters[i]))
				return false;
		return true;
	}

	private void buildContext(
			ASTNode astNode,
			ASTNode astNodeParent,
			CompilationUnitDeclaration compilationUnitDeclaration,
			Binding qualifiedBinding,
			Scope scope) {
		InternalCompletionContext context = new InternalCompletionContext();
		if (this.requestor.isExtendedContextRequired()) {
			context.setExtendedData(
					this.typeRoot,
					compilationUnitDeclaration,
					this.lookupEnvironment,
					scope,
					astNode,
					this.owner,
					this.parser);
		}

		// build expected types context
		if (this.expectedTypesPtr > -1) {
			int length = this.expectedTypesPtr + 1;
			char[][] expTypes = new char[length][];
			char[][] expKeys = new char[length][];
			for (int i = 0; i < length; i++) {
				expTypes[i] = getSignature(this.expectedTypes[i]);
				expKeys[i] = this.expectedTypes[i].computeUniqueKey();
			}
			context.setExpectedTypesSignatures(expTypes);
			context.setExpectedTypesKeys(expKeys);
		}

		context.setOffset(this.actualCompletionPosition + 1 - this.offset);

		// Set javadoc info
		if (astNode instanceof CompletionOnJavadoc) {
			this.assistNodeInJavadoc = ((CompletionOnJavadoc)astNode).getCompletionFlags();
			context.setJavadoc(this.assistNodeInJavadoc);
		}

		if (!(astNode instanceof CompletionOnJavadoc)) {
			CompletionScanner scanner = (CompletionScanner)this.parser.scanner;
			context.setToken(scanner.completionIdentifier);
			context.setTokenRange(
					scanner.completedIdentifierStart - this.offset,
					scanner.completedIdentifierEnd - this.offset,
					scanner.endOfEmptyToken - this.offset);
		} else if(astNode instanceof CompletionOnJavadocTag) {
			CompletionOnJavadocTag javadocTag = (CompletionOnJavadocTag) astNode;
			context.setToken(CharOperation.concat(new char[]{'@'}, javadocTag.token));
			context.setTokenRange(
					javadocTag.tagSourceStart - this.offset,
					javadocTag.tagSourceEnd - this.offset,
					((CompletionScanner)this.parser.javadocParser.scanner).endOfEmptyToken - this.offset);
		} else {
			CompletionScanner scanner = (CompletionScanner)this.parser.javadocParser.scanner;
			context.setToken(scanner.completionIdentifier);
			context.setTokenRange(
					scanner.completedIdentifierStart - this.offset,
					scanner.completedIdentifierEnd - this.offset,
					scanner.endOfEmptyToken - this.offset);
		}

		if(astNode instanceof CompletionOnStringLiteral) {
			context.setTokenKind(CompletionContext.TOKEN_KIND_STRING_LITERAL);
		} else {
			context.setTokenKind(CompletionContext.TOKEN_KIND_NAME);
		}

		buildTokenLocationContext(context, scope, astNode, astNodeParent);

		if(DEBUG) {
			System.out.println(context.toString());
		}
		this.requestor.acceptContext(context);
	}

	private void buildTokenLocationContext(InternalCompletionContext context, Scope scope, ASTNode astNode, ASTNode astNodeParent) {
		if (scope == null || context.isInJavadoc()) return;

		if (astNode instanceof CompletionOnFieldType) {
			CompletionOnFieldType field = (CompletionOnFieldType) astNode;
			if (!field.isLocalVariable &&
					field.modifiers == ClassFileConstants.AccDefault &&
					(field.annotations == null || field.annotations.length == 0)) {
				context.setTokenLocation(CompletionContext.TL_MEMBER_START);
			}
		} else if (astNode instanceof CompletionOnMethodReturnType) {
			CompletionOnMethodReturnType method = (CompletionOnMethodReturnType) astNode;
			if (method.modifiers == ClassFileConstants.AccDefault &&
					(method.annotations == null || method.annotations.length == 0)) {
				context.setTokenLocation(CompletionContext.TL_MEMBER_START);
			}
		} else {
			ReferenceContext referenceContext = scope.referenceContext();
			if (referenceContext instanceof AbstractMethodDeclaration) {
				AbstractMethodDeclaration methodDeclaration = (AbstractMethodDeclaration)referenceContext;
				if (methodDeclaration.bodyStart <= astNode.sourceStart &&
						astNode.sourceEnd <= methodDeclaration.bodyEnd) {
					// completion is inside a method body
					if (astNodeParent == null &&
							astNode instanceof CompletionOnSingleNameReference &&
							!((CompletionOnSingleNameReference)astNode).isPrecededByModifiers) {
						context.setTokenLocation(CompletionContext.TL_STATEMENT_START);
					}
				}
			} else if (referenceContext instanceof TypeDeclaration) {
				TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext;
				FieldDeclaration[] fields = typeDeclaration.fields;
				if (fields != null) {
					done : for (int i = 0; i < fields.length; i++) {
						if (fields[i] instanceof Initializer) {
							Initializer initializer = (Initializer) fields[i];
							if (initializer.block.sourceStart <= astNode.sourceStart &&
									astNode.sourceStart < initializer.bodyEnd) {
								// completion is inside an initializer
								if (astNodeParent == null &&
										astNode instanceof CompletionOnSingleNameReference &&
										!((CompletionOnSingleNameReference)astNode).isPrecededByModifiers) {
									context.setTokenLocation(CompletionContext.TL_STATEMENT_START);
								}
								break done;
							}
						}
					}
				}
			}
		}
	}

	void checkCancel() {
		if (this.monitor != null && this.monitor.isCanceled()) {
			throw new OperationCanceledException();
		}
	}

	private boolean complete(
			ASTNode astNode,
			ASTNode astNodeParent,
			ASTNode enclosingNode,
			CompilationUnitDeclaration compilationUnitDeclaration,
			Binding qualifiedBinding,
			Scope scope,
			boolean insideTypeAnnotation) {

		setSourceAndTokenRange(astNode.sourceStart, astNode.sourceEnd);

		scope = computeForbiddenBindings(astNode, astNodeParent, scope);
		computeUninterestingBindings(astNodeParent, scope);
		if(astNodeParent != null) {
			if(!isValidParent(astNodeParent, astNode, scope)) return false;
			computeExpectedTypes(astNodeParent, astNode, scope);
		}

		buildContext(astNode, astNodeParent, compilationUnitDeclaration, qualifiedBinding, scope);

		if (astNode instanceof CompletionOnFieldType) {
			completionOnFieldType(astNode, scope);
		} else if (astNode instanceof CompletionOnMethodReturnType) {
			completionOnMethodReturnType(astNode, scope);
		} else if (astNode instanceof CompletionOnSingleNameReference) {
			completionOnSingleNameReference(astNode, astNodeParent, scope, insideTypeAnnotation);
		} else if (astNode instanceof CompletionOnSingleTypeReference) {
			completionOnSingleTypeReference(astNode, astNodeParent, qualifiedBinding, scope);
		} else if (astNode instanceof CompletionOnQualifiedNameReference) {
			completionOnQualifiedNameReference(astNode, enclosingNode, qualifiedBinding, scope, insideTypeAnnotation);
		} else if (astNode instanceof CompletionOnQualifiedTypeReference) {
			completionOnQualifiedTypeReference(astNode, astNodeParent, qualifiedBinding, scope);
		} else if (astNode instanceof CompletionOnMemberAccess) {
			completionOnMemberAccess(astNode, enclosingNode, qualifiedBinding, scope, insideTypeAnnotation);
		} else if (astNode instanceof CompletionOnMessageSend) {
			completionOnMessageSend(astNode, qualifiedBinding, scope);
		} else if (astNode instanceof CompletionOnExplicitConstructorCall) {
			completionOnExplicitConstructorCall(astNode, qualifiedBinding, scope);
		} else if (astNode instanceof CompletionOnQualifiedAllocationExpression) {
			completionOnQualifiedAllocationExpression(astNode, qualifiedBinding, scope);
		} else if (astNode instanceof CompletionOnClassLiteralAccess) {
			completionOnClassLiteralAccess(astNode, qualifiedBinding, scope);
		} else if (astNode instanceof CompletionOnMethodName) {
			completionOnMethodName(astNode, scope);
		} else if (astNode instanceof CompletionOnFieldName) {
			completionOnFieldName(astNode, scope);
		} else if (astNode instanceof CompletionOnLocalName) {
			completionOnLocalOrArgumentName(astNode, scope);
		} else if (astNode instanceof CompletionOnArgumentName) {
			completionOnLocalOrArgumentName(astNode, scope);
		} else if (astNode instanceof CompletionOnKeyword) {
			completionOnKeyword(astNode);
		} else if (astNode instanceof CompletionOnParameterizedQualifiedTypeReference) {
			completionOnParameterizedQualifiedTypeReference(astNode, astNodeParent, qualifiedBinding, scope);
		} else if (astNode instanceof CompletionOnMarkerAnnotationName) {
			completionOnMarkerAnnotationName(astNode, qualifiedBinding, scope);
		} else if (astNode instanceof CompletionOnMemberValueName) {
			completionOnMemberValueName(astNode, astNodeParent, scope, insideTypeAnnotation);
		} else if(astNode instanceof CompletionOnBranchStatementLabel) {
			completionOnBranchStatementLabel(astNode);
		} else if(astNode instanceof CompletionOnMessageSendName) {
			completionOnMessageSendName(astNode, qualifiedBinding, scope);
		// Completion on Javadoc nodes
		} else if ((astNode.bits & ASTNode.InsideJavadoc) != 0) {
			if (astNode instanceof CompletionOnJavadocSingleTypeReference) {
				completionOnJavadocSingleTypeReference(astNode, scope);
			} else if (astNode instanceof CompletionOnJavadocQualifiedTypeReference) {
				completionOnJavadocQualifiedTypeReference(astNode, qualifiedBinding, scope);
			} else if (astNode instanceof CompletionOnJavadocFieldReference) {
				completionOnJavadocFieldReference(astNode, scope);
			} else if (astNode instanceof CompletionOnJavadocMessageSend) {
				completionOnJavadocMessageSend(astNode, qualifiedBinding, scope);
			} else if (astNode instanceof CompletionOnJavadocAllocationExpression) {
				completionOnJavadocAllocationExpression(astNode, qualifiedBinding, scope);
			} else if (astNode instanceof CompletionOnJavadocParamNameReference) {
				completionOnJavadocParamNameReference(astNode);
			} else if (astNode instanceof CompletionOnJavadocTypeParamReference) {
				completionOnJavadocTypeParamReference(astNode);
			} else if (astNode instanceof CompletionOnJavadocTag) {
				completionOnJavadocTag(astNode);
			}
		}
		return true;
	}

	/**
	 * Ask the engine to compute a completion at the specified position
	 * of the given compilation unit.
	 *
	 *  No return
	 *      completion results are answered through a requestor.
	 *
	 *  @param sourceUnit org.eclipse.jdt.internal.compiler.env.ICompilationUnit
	 *      the source of the current compilation unit.
	 *
	 *  @param completionPosition int
	 *      a position in the source where the completion is taking place.
	 *      This position is relative to the source provided.
	 */
	public void complete(ICompilationUnit sourceUnit, int completionPosition, int pos, ITypeRoot root) {

		if(DEBUG) {
			System.out.print("COMPLETION IN "); //$NON-NLS-1$
			System.out.print(sourceUnit.getFileName());
			System.out.print(" AT POSITION "); //$NON-NLS-1$
			System.out.println(completionPosition);
			System.out.println("COMPLETION - Source :"); //$NON-NLS-1$
			System.out.println(sourceUnit.getContents());
		}
		if (this.monitor != null) this.monitor.beginTask(Messages.engine_completing, IProgressMonitor.UNKNOWN);
		this.requestor.beginReporting();
		boolean contextAccepted = false;
		try {
			this.fileName = sourceUnit.getFileName();
			this.actualCompletionPosition = completionPosition - 1;
			this.offset = pos;
			this.typeRoot = root;
			
			this.checkCancel();
			
			// for now until we can change the UI.
			CompilationResult result = new CompilationResult(sourceUnit, 1, 1, this.compilerOptions.maxProblemsPerUnit);
			CompilationUnitDeclaration parsedUnit = this.parser.dietParse(sourceUnit, result, this.actualCompletionPosition);

			//		boolean completionNodeFound = false;
			if (parsedUnit != null) {
				if(DEBUG) {
					System.out.println("COMPLETION - Diet AST :"); //$NON-NLS-1$
					System.out.println(parsedUnit.toString());
				}

				// scan the package & import statements first
				if (parsedUnit.currentPackage instanceof CompletionOnPackageReference) {
					contextAccepted = true;
					buildContext(parsedUnit.currentPackage, null, parsedUnit, null, null);
					if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
						findPackages((CompletionOnPackageReference) parsedUnit.currentPackage);
					}
					if(this.noProposal && this.problem != null) {
						this.requestor.completionFailure(this.problem);
						if(DEBUG) {
							this.printDebug(this.problem);
						}
					}
					return;
				}

				ImportReference[] imports = parsedUnit.imports;
				if (imports != null) {
					for (int i = 0, length = imports.length; i < length; i++) {
						ImportReference importReference = imports[i];
						if (importReference instanceof CompletionOnImportReference) {
							this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
							if ((this.unitScope = parsedUnit.scope) != null) {
								contextAccepted = true;
								buildContext(importReference, null, parsedUnit, null, null);

								long positions = importReference.sourcePositions[importReference.tokens.length - 1];
								setSourceAndTokenRange((int) (positions >>> 32), (int) positions);

								char[][] oldTokens = importReference.tokens;
								int tokenCount = oldTokens.length;
								if (tokenCount == 1) {
									findImports((CompletionOnImportReference)importReference, true);
								} else if(tokenCount > 1){
									this.insideQualifiedReference = true;

									char[] lastToken = oldTokens[tokenCount - 1];
									char[][] qualifierTokens = CharOperation.subarray(oldTokens, 0, tokenCount - 1);

									Binding binding = this.unitScope.getTypeOrPackage(qualifierTokens);
									if(binding != null) {
										if(binding instanceof PackageBinding) {
											findImports((CompletionOnImportReference)importReference, false);
										} else {
											ReferenceBinding ref = (ReferenceBinding) binding;

											if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
												findImportsOfMemberTypes(lastToken, ref, importReference.isStatic());
											}
											if(importReference.isStatic()) {

												if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
													findImportsOfStaticFields(lastToken, ref);
												}
												if(!this.requestor.isIgnored(CompletionProposal.METHOD_NAME_REFERENCE)) {
													findImportsOfStaticMethods(lastToken, ref);
												}
											}
										}
									}
								}

								if(this.noProposal && this.problem != null) {
									this.requestor.completionFailure(this.problem);
									if(DEBUG) {
										this.printDebug(this.problem);
									}
								}
							}
							return;
						} else if(importReference instanceof CompletionOnKeyword) {
							contextAccepted = true;
							buildContext(importReference, null, parsedUnit, null, null);
							if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
								setSourceAndTokenRange(importReference.sourceStart, importReference.sourceEnd);
								CompletionOnKeyword keyword = (CompletionOnKeyword)importReference;
								findKeywords(keyword.getToken(), keyword.getPossibleKeywords(), false, false);
							}
							if(this.noProposal && this.problem != null) {
								this.requestor.completionFailure(this.problem);
								if(DEBUG) {
									this.printDebug(this.problem);
								}
							}
							return;
						}
					}
				}

				if (parsedUnit.types != null) {
					try {
						this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);

						if ((this.unitScope = parsedUnit.scope) != null) {
							this.source = sourceUnit.getContents();
							this.lookupEnvironment.completeTypeBindings(parsedUnit, true);
							parsedUnit.scope.faultInTypes();
							parseBlockStatements(parsedUnit, this.actualCompletionPosition);
							if(DEBUG) {
								System.out.println("COMPLETION - AST :"); //$NON-NLS-1$
								System.out.println(parsedUnit.toString());
							}
							parsedUnit.resolve();
						}
					} catch (CompletionNodeFound e) {
						//					completionNodeFound = true;
						if (e.astNode != null) {
							// if null then we found a problem in the completion node
							if(DEBUG) {
								System.out.print("COMPLETION - Completion node : "); //$NON-NLS-1$
								System.out.println(e.astNode.toString());
								if(this.parser.assistNodeParent != null) {
									System.out.print("COMPLETION - Parent Node : ");  //$NON-NLS-1$
									System.out.println(this.parser.assistNodeParent);
								}
							}
							this.lookupEnvironment.unitBeingCompleted = parsedUnit; // better resilient to further error reporting
							contextAccepted =
								complete(
									e.astNode,
									this.parser.assistNodeParent,
									this.parser.enclosingNode,
									parsedUnit,
									e.qualifiedBinding,
									e.scope,
									e.insideTypeAnnotation);
						}
					}
				}
			}

			if(this.noProposal && this.problem != null) {
				if(!contextAccepted) {
					contextAccepted = true;
					InternalCompletionContext context = new InternalCompletionContext();
					context.setOffset(completionPosition - this.offset);
					context.setTokenKind(CompletionContext.TOKEN_KIND_UNKNOWN);
					if (this.requestor.isExtendedContextRequired()) context.setExtended();
					this.requestor.acceptContext(context);
				}
				this.requestor.completionFailure(this.problem);
				if(DEBUG) {
					this.printDebug(this.problem);
				}
			}
			/* Ignore package, import, class & interface keywords for now...
					if (!completionNodeFound) {
						if (parsedUnit == null || parsedUnit.types == null) {
							// this is not good enough... can still be trying to define a second type
							CompletionScanner scanner = (CompletionScanner) this.parser.scanner;
							setSourceRange(scanner.completedIdentifierStart, scanner.completedIdentifierEnd);
							findKeywords(scanner.completionIdentifier, mainDeclarations, null);
						}
						// currently have no way to know if extends/implements are possible keywords
					}
			*/
		} catch (IndexOutOfBoundsException e) { // work-around internal failure - 1GEMF6D
			if(DEBUG) {
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
				e.printStackTrace(System.out);
			}
		} catch (InvalidCursorLocation e) { // may eventually report a usefull error
			if(DEBUG) {
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
				e.printStackTrace(System.out);
			}
		} catch (AbortCompilation e) { // ignore this exception for now since it typically means we cannot find java.lang.Object
			if(DEBUG) {
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
				e.printStackTrace(System.out);
			}
		} catch (CompletionNodeFound e){ // internal failure - bugs 5618
			if(DEBUG) {
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
				e.printStackTrace(System.out);
			}
		} finally {
			if(!contextAccepted) {
				contextAccepted = true;
				InternalCompletionContext context = new InternalCompletionContext();
				context.setTokenKind(CompletionContext.TOKEN_KIND_UNKNOWN);
				context.setOffset(completionPosition - this.offset);
				if (this.requestor.isExtendedContextRequired()) context.setExtended();
				this.requestor.acceptContext(context);
			}
			this.requestor.endReporting();
			if (this.monitor != null) this.monitor.done();
			reset();
		}
	}

	public void complete(IType type, char[] snippet, int position, char[][] localVariableTypeNames, char[][] localVariableNames, int[] localVariableModifiers, boolean isStatic){
		if(this.requestor != null){
			this.requestor.beginReporting();
		}
		boolean contextAccepted = false;
		IType topLevelType = type;
		while(topLevelType.getDeclaringType() != null) {
			topLevelType = topLevelType.getDeclaringType();
		}

		this.fileName = topLevelType.getParent().getElementName().toCharArray();
		CompilationResult compilationResult = new CompilationResult(this.fileName, 1, 1, this.compilerOptions.maxProblemsPerUnit);

		CompilationUnitDeclaration compilationUnit = null;

		try {
			// TypeConverter is used instead of SourceTypeConverter because the type
			// to convert can be a binary type or a source type
			TypeDeclaration typeDeclaration = null;
			if (type instanceof SourceType) {
				SourceType sourceType = (SourceType) type;
				ISourceType info = (ISourceType) sourceType.getElementInfo();
				compilationUnit = SourceTypeConverter.buildCompilationUnit(
					new ISourceType[] {info},//sourceTypes[0] is always toplevel here
					SourceTypeConverter.FIELD_AND_METHOD // need field and methods
					| SourceTypeConverter.MEMBER_TYPE, // need member types
					// no need for field initialization
					this.problemReporter,
					compilationResult);
				if (compilationUnit.types != null)
					typeDeclaration = compilationUnit.types[0];
			} else {
				compilationUnit = new CompilationUnitDeclaration(this.problemReporter, compilationResult, 0);
				typeDeclaration = new BinaryTypeConverter(this.parser.problemReporter(), compilationResult, null/*no need to remember type names*/).buildTypeDeclaration(type, compilationUnit);
			}

			if(typeDeclaration != null) {
				// build AST from snippet
				Initializer fakeInitializer = parseSnippeInitializer(snippet, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic);

				// merge AST
				FieldDeclaration[] oldFields = typeDeclaration.fields;
				FieldDeclaration[] newFields = null;
				if (oldFields != null) {
					newFields = new FieldDeclaration[oldFields.length + 1];
					System.arraycopy(oldFields, 0, newFields, 0, oldFields.length);
					newFields[oldFields.length] = fakeInitializer;
				} else {
					newFields = new FieldDeclaration[] {fakeInitializer};
				}
				typeDeclaration.fields = newFields;

				if(DEBUG) {
					System.out.println("SNIPPET COMPLETION AST :"); //$NON-NLS-1$
					System.out.println(compilationUnit.toString());
				}

				if (compilationUnit.types != null) {
					try {
						this.lookupEnvironment.buildTypeBindings(compilationUnit, null /*no access restriction*/);

						if ((this.unitScope = compilationUnit.scope) != null) {
							this.lookupEnvironment.completeTypeBindings(compilationUnit, true);
							compilationUnit.scope.faultInTypes();
							compilationUnit.resolve();
						}
					} catch (CompletionNodeFound e) {
						//					completionNodeFound = true;
						if (e.astNode != null) {
							// if null then we found a problem in the completion node
							contextAccepted =
								complete(
									e.astNode,
									this.parser.assistNodeParent,
									this.parser.enclosingNode,
									compilationUnit,
									e.qualifiedBinding,
									e.scope,
									e.insideTypeAnnotation);
						}
					}
				}
				if(this.noProposal && this.problem != null) {
					if(!contextAccepted) {
						contextAccepted = true;
						InternalCompletionContext context = new InternalCompletionContext();
						if (this.requestor.isExtendedContextRequired()) context.setExtended();
						this.requestor.acceptContext(context);
					}
					this.requestor.completionFailure(this.problem);
					if(DEBUG) {
						this.printDebug(this.problem);
					}
				}
			}
		}  catch (IndexOutOfBoundsException e) { // work-around internal failure - 1GEMF6D (added with fix of 99629)
			if(DEBUG) {
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
				e.printStackTrace(System.out);
			}
		} catch (InvalidCursorLocation e) { // may eventually report a usefull error (added to fix 99629)
			if(DEBUG) {
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
				e.printStackTrace(System.out);
			}
		} catch (AbortCompilation e) { // ignore this exception for now since it typically means we cannot find java.lang.Object (added with fix of 99629)
			if(DEBUG) {
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
				e.printStackTrace(System.out);
			}
		} catch (CompletionNodeFound e){ // internal failure - bugs 5618 (added with fix of 99629)
			if(DEBUG) {
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
				e.printStackTrace(System.out);
			}
		} catch(JavaModelException e) {
			// Do nothing
		}
		if(!contextAccepted) {
			contextAccepted = true;
			InternalCompletionContext context = new InternalCompletionContext();
			if (this.requestor.isExtendedContextRequired()) context.setExtended();
			this.requestor.acceptContext(context);
		}
		if(this.requestor != null){
			this.requestor.endReporting();
		}
	}
	
	private void completionOnBranchStatementLabel(ASTNode astNode) {
		if (!this.requestor.isIgnored(CompletionProposal.LABEL_REF)) {
			CompletionOnBranchStatementLabel label = (CompletionOnBranchStatementLabel) astNode;
			this.completionToken = label.label;
			findLabels(this.completionToken, label.possibleLabels);
		}
	}
	
	private void completionOnClassLiteralAccess(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
		if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
			CompletionOnClassLiteralAccess access = (CompletionOnClassLiteralAccess) astNode;
			setSourceAndTokenRange(access.classStart, access.sourceEnd);
			this.completionToken = access.completionIdentifier;
			findClassField(
					this.completionToken,
					(TypeBinding) qualifiedBinding,
					scope,
					null,
					null,
					null,
					false);
		}
	}
	
	private void completionOnExplicitConstructorCall(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
		if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
			setSourceAndTokenRange(astNode.sourceStart, astNode.sourceEnd, false);
			CompletionOnExplicitConstructorCall constructorCall = (CompletionOnExplicitConstructorCall) astNode;
			TypeBinding[] argTypes = computeTypes(constructorCall.arguments);
			findConstructors(
				(ReferenceBinding) qualifiedBinding,
				argTypes,
				scope,
				constructorCall,
				false,
				null,
				null,
				null,
				false);
		}
	}
	
	private void completionOnFieldName(ASTNode astNode, Scope scope) {
		if (!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
			CompletionOnFieldName field = (CompletionOnFieldName) astNode;

			FieldBinding[] fields = scope.enclosingSourceType().fields();
			char[][] excludeNames = new char[fields.length][];
			for(int i = 0 ; i < fields.length ; i++){
				excludeNames[i] = fields[i].name;
			}

			this.completionToken = field.realName;

			
			int kind =
				 (field.modifiers & ClassFileConstants.AccStatic) == 0 ? 
						InternalNamingConventions.VK_INSTANCE_FIELD :
							(field.modifiers & ClassFileConstants.AccFinal) == 0 ? 
									InternalNamingConventions.VK_STATIC_FIELD :
										InternalNamingConventions.VK_STATIC_FINAL_FIELD;
			
			findVariableNames(field.realName, field.type, excludeNames, null, kind);
		}
	}
	
	private void completionOnFieldType(ASTNode astNode, Scope scope) {
		CompletionOnFieldType field = (CompletionOnFieldType) astNode;
		CompletionOnSingleTypeReference type = (CompletionOnSingleTypeReference) field.type;
		this.completionToken = type.token;
		setSourceAndTokenRange(type.sourceStart, type.sourceEnd);

		findTypesAndPackages(this.completionToken, scope, true, true, new ObjectVector());
		if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
			findKeywordsForMember(this.completionToken, field.modifiers);
		}

		if (!field.isLocalVariable && field.modifiers == ClassFileConstants.AccDefault) {
			SourceTypeBinding enclosingType = scope.enclosingSourceType();
			if (!enclosingType.isAnnotationType()) {
				if (!this.requestor.isIgnored(CompletionProposal.METHOD_DECLARATION)) {
					findMethodDeclarations(
							this.completionToken,
							enclosingType,
							scope,
							new ObjectVector(),
							null,
							null,
							null,
							false);
				}
				if (!this.requestor.isIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION)) {
					proposeNewMethod(this.completionToken, enclosingType);
				}
			}
		}
	}
	//TODO
	private void completionOnJavadocAllocationExpression(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
		// setSourceRange(astNode.sourceStart, astNode.sourceEnd, false);
		
		CompletionOnJavadocAllocationExpression allocExpression = (CompletionOnJavadocAllocationExpression) astNode;
		this.javadocTagPosition = allocExpression.tagSourceStart;
		int rangeStart = astNode.sourceStart;
		if (allocExpression.type.isThis()) {
			if (allocExpression.completeInText()) {
				rangeStart = allocExpression.separatorPosition;
			}
		} else if (allocExpression.completeInText()) {
			rangeStart = allocExpression.type.sourceStart;
		}
		setSourceAndTokenRange(rangeStart, astNode.sourceEnd, false);
		TypeBinding[] argTypes = computeTypes(allocExpression.arguments);

		ReferenceBinding ref = (ReferenceBinding) qualifiedBinding;
		if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF) && ref.isClass()) {
			findConstructors(ref, argTypes, scope, allocExpression, false, null, null, null, false);
		}
	}
	//TODO
	private void completionOnJavadocFieldReference(ASTNode astNode, Scope scope) {
		this.insideQualifiedReference = true;
		CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) astNode;
		this.completionToken = fieldRef.token;
		long completionPosition = fieldRef.nameSourcePosition;
		this.javadocTagPosition = fieldRef.tagSourceStart;

		if (fieldRef.actualReceiverType != null && fieldRef.actualReceiverType.isValidBinding()) {
				ReferenceBinding receiverType = (ReferenceBinding) fieldRef.actualReceiverType;
			int rangeStart = (int) (completionPosition >>> 32);
			if (fieldRef.receiver.isThis()) {
				if (fieldRef.completeInText()) {
					rangeStart = fieldRef.separatorPosition;
				}
			} else if (fieldRef.completeInText()) {
				rangeStart = fieldRef.receiver.sourceStart;
			}
			setSourceAndTokenRange(rangeStart, (int) completionPosition);

			if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)
					|| !this.requestor.isIgnored(CompletionProposal.JAVADOC_FIELD_REF)) {
				findFields(this.completionToken,
					receiverType,
					scope,
					new ObjectVector(),
					new ObjectVector(),
					false, /*not only static */
					fieldRef,
					scope,
					false,
					true,
					null,
					null,
					null,
					false,
					null,
					-1,
					-1);
			}

			if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)
					|| !this.requestor.isIgnored(CompletionProposal.JAVADOC_METHOD_REF)) {
				findMethods(
					this.completionToken,
					null,
					null,
					receiverType,
					scope,
					new ObjectVector(),
					false, /*not only static */
					false,
					fieldRef,
					scope,
					false,
					false,
					true,
					null,
					null,
					null,
					false,
					null,
					-1,
					-1);
				if (fieldRef.actualReceiverType instanceof ReferenceBinding) {
					ReferenceBinding refBinding = (ReferenceBinding)fieldRef.actualReceiverType;
					if (this.completionToken == null
							|| CharOperation.prefixEquals(this.completionToken, refBinding.sourceName)
							|| (this.options.camelCaseMatch && CharOperation.camelCaseMatch(this.completionToken, refBinding.sourceName))) {
						findConstructors(refBinding, null, scope, fieldRef, false, null, null, null, false);
					}
				}
			}
		}
	}
	//TODO
	private void completionOnJavadocMessageSend(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
		CompletionOnJavadocMessageSend messageSend = (CompletionOnJavadocMessageSend) astNode;
		TypeBinding[] argTypes = null; //computeTypes(messageSend.arguments);
		this.completionToken = messageSend.selector;
		this.javadocTagPosition = messageSend.tagSourceStart;

		// Set source range
		int rangeStart = astNode.sourceStart;
		if (messageSend.receiver.isThis()) {
			if (messageSend.completeInText()) {
				rangeStart = messageSend.separatorPosition;
			}
		} else if (messageSend.completeInText()) {
			rangeStart = messageSend.receiver.sourceStart;
		}
		setSourceAndTokenRange(rangeStart, astNode.sourceEnd, false);

		if (qualifiedBinding == null) {
			if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
				findImplicitMessageSends(this.completionToken, argTypes, scope, messageSend, scope, new ObjectVector());
			}
		} else if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
			findMethods(
				this.completionToken,
				null,
				argTypes,
				(ReferenceBinding) ((ReferenceBinding) qualifiedBinding).capture(scope, messageSend.receiver.sourceEnd),
				scope,
				new ObjectVector(),
				false,
				false/* prefix match */,
				messageSend,
				scope,
				false,
				messageSend.receiver instanceof SuperReference,
				true,
				null,
				null,
				null,
				false,
				null,
				-1,
				-1);
		}
	}
	//TODO
	private void completionOnJavadocParamNameReference(ASTNode astNode) {
		if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_PARAM_REF)) {
			CompletionOnJavadocParamNameReference paramRef = (CompletionOnJavadocParamNameReference) astNode;
			setSourceAndTokenRange(paramRef.tagSourceStart, paramRef.tagSourceEnd);
			findJavadocParamNames(paramRef.token, paramRef.missingParams, false);
			findJavadocParamNames(paramRef.token, paramRef.missingTypeParams, true);
		}
	}
	//TODO
	private void completionOnJavadocQualifiedTypeReference(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
		this.insideQualifiedReference = true;

		CompletionOnJavadocQualifiedTypeReference typeRef = (CompletionOnJavadocQualifiedTypeReference) astNode;
		this.completionToken = typeRef.completionIdentifier;
		long completionPosition = typeRef.sourcePositions[typeRef.tokens.length];
		this.javadocTagPosition = typeRef.tagSourceStart;

		// get the source positions of the completion identifier
		if (qualifiedBinding instanceof ReferenceBinding && !(qualifiedBinding instanceof TypeVariableBinding)) {
			if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF) ||
					((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF))) {
				int rangeStart = typeRef.completeInText() ? typeRef.sourceStart : (int) (completionPosition >>> 32);
				setSourceAndTokenRange(rangeStart, (int) completionPosition);
				findMemberTypes(
					this.completionToken,
					(ReferenceBinding) qualifiedBinding,
					scope,
					scope.enclosingSourceType(),
					false,
					false,
					new ObjectVector(),
					null,
					null,
					null,
					false);
			}
		} else if (qualifiedBinding instanceof PackageBinding) {

			setSourceRange(astNode.sourceStart, (int) completionPosition);
			int rangeStart = typeRef.completeInText() ? typeRef.sourceStart : (int) (completionPosition >>> 32);
			setTokenRange(rangeStart, (int) completionPosition);
			// replace to the end of the completion identifier
			findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
		}
	}
	//TODO
	private void completionOnJavadocSingleTypeReference(ASTNode astNode, Scope scope) {
		CompletionOnJavadocSingleTypeReference typeRef = (CompletionOnJavadocSingleTypeReference) astNode;
		this.completionToken = typeRef.token;
		this.javadocTagPosition = typeRef.tagSourceStart;
		setSourceAndTokenRange(typeRef.sourceStart, typeRef.sourceEnd);
		findTypesAndPackages(
				this.completionToken,
				scope,
				(this.assistNodeInJavadoc & CompletionOnJavadoc.BASE_TYPES) != 0,
				false,
				new ObjectVector());
	}
	//TODO
	private void completionOnJavadocTag(ASTNode astNode) {
		CompletionOnJavadocTag javadocTag = (CompletionOnJavadocTag) astNode;
		setSourceAndTokenRange(javadocTag.tagSourceStart, javadocTag.sourceEnd);
		findJavadocBlockTags(javadocTag);
		findJavadocInlineTags(javadocTag);
	}
	//TODO
	private void completionOnJavadocTypeParamReference(ASTNode astNode) {
		if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_PARAM_REF)) {
			CompletionOnJavadocTypeParamReference paramRef = (CompletionOnJavadocTypeParamReference) astNode;
			setSourceAndTokenRange(paramRef.tagSourceStart, paramRef.tagSourceEnd);
			findJavadocParamNames(paramRef.token, paramRef.missingParams, true);
		}
	}
	
	private void completionOnKeyword(ASTNode astNode) {
		if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
			CompletionOnKeyword keyword = (CompletionOnKeyword)astNode;
			findKeywords(keyword.getToken(), keyword.getPossibleKeywords(), keyword.canCompleteEmptyToken(), false);
		}
	}
	
	private void completionOnLocalOrArgumentName(ASTNode astNode, Scope scope) {
		if (!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
			LocalDeclaration variable = (LocalDeclaration) astNode;

			int kind;
			if (variable instanceof CompletionOnLocalName){
				this.completionToken = ((CompletionOnLocalName) variable).realName;
				kind = InternalNamingConventions.VK_LOCAL;
			} else {
				CompletionOnArgumentName arg = (CompletionOnArgumentName) variable;
				this.completionToken = arg.realName;
				kind = arg.isCatchArgument ? InternalNamingConventions.VK_LOCAL : InternalNamingConventions.VK_PARAMETER;
			}

			char[][] alreadyDefinedName = computeAlreadyDefinedName((BlockScope)scope, variable);

			char[][] forbiddenNames = findVariableFromUnresolvedReference(variable, (BlockScope)scope, alreadyDefinedName);

			LocalVariableBinding[] locals = ((BlockScope)scope).locals;
			char[][] discouragedNames = new char[locals.length][];
			int localCount = 0;
			for(int i = 0 ; i < locals.length ; i++){
				if (locals[i] != null) {
					discouragedNames[localCount++] = locals[i].name;
				}
			}

			System.arraycopy(discouragedNames, 0, discouragedNames = new char[localCount][], 0, localCount);

			findVariableNames(this.completionToken, variable.type, discouragedNames, forbiddenNames, kind);
		}
	}
	
	private void completionOnMarkerAnnotationName(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
		CompletionOnMarkerAnnotationName annot = (CompletionOnMarkerAnnotationName) astNode;

		CompletionOnAnnotationOfType fakeType = (CompletionOnAnnotationOfType)scope.parent.referenceContext();
		if (fakeType.annotations[0] == annot) {
			// When the completion is inside a method body the annotation cannot be accuratly attached to the correct node by completion recovery.
			// So 'targetedElement' is not computed in this case.
			if (scope.parent.parent == null || !(scope.parent.parent instanceof MethodScope)) {
				this.targetedElement = computeTargetedElement(fakeType);
			}

		}

		this.assistNodeIsAnnotation = true;
		if (annot.type instanceof CompletionOnSingleTypeReference) {
			CompletionOnSingleTypeReference type = (CompletionOnSingleTypeReference) annot.type;
			this.completionToken = type.token;
			setSourceAndTokenRange(type.sourceStart, type.sourceEnd);

			if (scope.parent.parent != null &&
					!(scope.parent.parent instanceof MethodScope) &&
					!fakeType.isParameter) {

				if (this.completionToken.length <= Keywords.INTERFACE.length
					&& CharOperation.prefixEquals(this.completionToken, Keywords.INTERFACE, false /* ignore case */
				)){
					int relevance = computeBaseRelevance();
					relevance += computeRelevanceForResolution();
					relevance += computeRelevanceForInterestingProposal();
					relevance += computeRelevanceForCaseMatching(this.completionToken, Keywords.INTERFACE);
					relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywords
					relevance += R_ANNOTATION; // this proposal is most relevant than annotation proposals

					this.noProposal = false;
					if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
						CompletionProposal proposal = createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
						proposal.setName(Keywords.INTERFACE);
						proposal.setCompletion(Keywords.INTERFACE);
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
						proposal.setRelevance(relevance);
						this.requestor.accept(proposal);
						if(DEBUG) {
							this.printDebug(proposal);
						}
					}
				}
			}

			findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
		} else if (annot.type instanceof CompletionOnQualifiedTypeReference) {
			this.insideQualifiedReference = true;

			CompletionOnQualifiedTypeReference type = (CompletionOnQualifiedTypeReference) annot.type;
			this.completionToken = type.completionIdentifier;
			long completionPosition = type.sourcePositions[type.tokens.length];
			if (qualifiedBinding instanceof PackageBinding) {

				setSourceRange(astNode.sourceStart, (int) completionPosition);
				setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
				// replace to the end of the completion identifier
				findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
			} else {
				setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);

				findMemberTypes(
					this.completionToken,
					(ReferenceBinding) qualifiedBinding,
					scope,
					scope.enclosingSourceType(),
					false,
					false,
					new ObjectVector(),
					null,
					null,
					null,
					false);
			}
		}
	}
	
	private void completionOnMemberAccess(ASTNode astNode, ASTNode enclosingNode, Binding qualifiedBinding,
			Scope scope, boolean insideTypeAnnotation) {
		this.insideQualifiedReference = true;
		CompletionOnMemberAccess access = (CompletionOnMemberAccess) astNode;
		long completionPosition = access.nameSourcePosition;
		setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);

		this.completionToken = access.token;

		if (qualifiedBinding.problemId() == ProblemReasons.NotFound) {
			// complete method members with missing return type
			// class X {
			//   Missing f() {return null;}
			//   void foo() {
			//     f().|
			//   }
			// }
			if (this.assistNodeInJavadoc == 0 &&
					(this.requestor.isAllowingRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_REF) ||
							this.requestor.isAllowingRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_REF))) {
				ProblemMethodBinding problemMethodBinding = (ProblemMethodBinding) qualifiedBinding;
				findFieldsAndMethodsFromMissingReturnType(
						problemMethodBinding.selector,
						problemMethodBinding.parameters,
						scope,
						access,
						insideTypeAnnotation);
			}
		} else {
			if (!access.isInsideAnnotation) {
				if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
					findKeywords(this.completionToken, new char[][]{Keywords.NEW}, false, false);
				}

				ObjectVector fieldsFound = new ObjectVector();
				ObjectVector methodsFound = new ObjectVector();

				boolean superCall = access.receiver instanceof SuperReference;

				findFieldsAndMethods(
					this.completionToken,
					((TypeBinding) qualifiedBinding).capture(scope, access.receiver.sourceEnd),
					scope,
					fieldsFound,
					methodsFound,
					access,
					scope,
					false,
					superCall,
					null,
					null,
					null,
					false,
					null,
					-1,
					-1);

				if (!superCall) {
					
					checkCancel();
					
					findFieldsAndMethodsFromCastedReceiver(
							enclosingNode,
							qualifiedBinding,
							scope,
							fieldsFound,
							methodsFound,
							access,
							scope,
							access.receiver);
				}
			}
		}
	}
	
	private void completionOnMemberValueName(ASTNode astNode, ASTNode astNodeParent, Scope scope,
			boolean insideTypeAnnotation) {
		CompletionOnMemberValueName memberValuePair = (CompletionOnMemberValueName) astNode;
		Annotation annotation = (Annotation) astNodeParent;

		this.completionToken = memberValuePair.name;

		ReferenceBinding annotationType = (ReferenceBinding)annotation.resolvedType;

		if (annotationType != null && annotationType.isAnnotationType()) {
			if (!this.requestor.isIgnored(CompletionProposal.ANNOTATION_ATTRIBUTE_REF)) {
				findAnnotationAttributes(this.completionToken, annotation.memberValuePairs(), annotationType);
			}
			if (this.assistNodeCanBeSingleMemberAnnotation) {
				if (this.expectedTypesPtr > -1 && this.expectedTypes[0].isAnnotationType()) {
					findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
				} else {
					if (this.expectedTypesPtr > -1) {
						this.assistNodeIsEnum = true;
						done : for (int i = 0; i <= this.expectedTypesPtr; i++) {
							if (!this.expectedTypes[i].isEnum()) {
								this.assistNodeIsEnum = false;
								break done;
							}
						}

					}
					if (scope instanceof BlockScope && !this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
						char[][] alreadyDefinedName = computeAlreadyDefinedName((BlockScope)scope, FakeInvocationSite);

						findUnresolvedReference(
								memberValuePair.sourceStart,
								memberValuePair.sourceEnd,
								(BlockScope)scope,
								alreadyDefinedName);
					}
					findVariablesAndMethods(
						this.completionToken,
						scope,
						FakeInvocationSite,
						scope,
						insideTypeAnnotation,
						true);
					// can be the start of a qualified type name
					findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
				}
			}
		}
	}
	
	private void completionOnMessageSend(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
		setSourceAndTokenRange(astNode.sourceStart, astNode.sourceEnd, false);

		CompletionOnMessageSend messageSend = (CompletionOnMessageSend) astNode;
		TypeBinding[] argTypes = computeTypes(messageSend.arguments);
		this.completionToken = messageSend.selector;
		if (qualifiedBinding == null) {
			if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
				ObjectVector methodsFound = new ObjectVector();

				findImplicitMessageSends(this.completionToken, argTypes, scope, messageSend, scope, methodsFound);
				
				checkCancel();
				
				findLocalMethodsFromStaticImports(
						this.completionToken,
						scope,
						messageSend,
						scope,
						true,
						methodsFound,
						true);
			}
		} else  if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
			findMethods(
				this.completionToken,
				null,
				argTypes,
				(ReferenceBinding)((ReferenceBinding) qualifiedBinding).capture(scope, messageSend.receiver.sourceEnd),
				scope,
				new ObjectVector(),
				false,
				true,
				messageSend,
				scope,
				false,
				messageSend.receiver instanceof SuperReference,
				false,
				null,
				null,
				null,
				false,
				null,
				-1,
				-1);
		}
	}
	
	private void completionOnMessageSendName(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
		if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
			CompletionOnMessageSendName messageSend = (CompletionOnMessageSendName) astNode;

			this.insideQualifiedReference = true;
			this.completionToken = messageSend.selector;
			boolean onlyStatic = false;
			if (messageSend.receiver instanceof NameReference) {
				onlyStatic = ((NameReference)messageSend.receiver).isTypeReference();
			} else if (!(messageSend.receiver instanceof MessageSend) &&
					!(messageSend.receiver instanceof FieldReference) &&
					!(messageSend.receiver.isThis())) {
				onlyStatic = true;
			}

			TypeBinding receiverType = (TypeBinding)qualifiedBinding;

			if(receiverType != null && receiverType instanceof ReferenceBinding) {
				TypeBinding[] typeArgTypes = computeTypesIfCorrect(messageSend.typeArguments);
				if(typeArgTypes != null) {
					findMethods(
							this.completionToken,
							typeArgTypes,
							null,
							(ReferenceBinding)receiverType.capture(scope, messageSend.receiver.sourceEnd),
							scope,
							new ObjectVector(),
							onlyStatic,
							false,
							messageSend,
							scope,
							false,
							false,
							false,
							null,
							null,
							null,
							false,
							null,
							-1,
							-1);
				}
			}
		}
	}
	
	private void completionOnMethodName(ASTNode astNode, Scope scope) {
		if (!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
			CompletionOnMethodName method = (CompletionOnMethodName) astNode;

			setSourceAndTokenRange(method.sourceStart, method.selectorEnd);

			FieldBinding[] fields = scope.enclosingSourceType().fields();
			char[][] excludeNames = new char[fields.length][];
			for(int i = 0 ; i < fields.length ; i++){
				excludeNames[i] = fields[i].name;
			}

			this.completionToken = method.selector;

			
			int kind =
				 (method.modifiers & ClassFileConstants.AccStatic) == 0 ? 
						InternalNamingConventions.VK_INSTANCE_FIELD :
							(method.modifiers & ClassFileConstants.AccFinal) == 0 ? 
									InternalNamingConventions.VK_STATIC_FIELD :
										InternalNamingConventions.VK_STATIC_FINAL_FIELD;
						
			findVariableNames(this.completionToken, method.returnType, excludeNames, null, kind);
		}
	}
	
	private void completionOnMethodReturnType(ASTNode astNode, Scope scope) {
		CompletionOnMethodReturnType method = (CompletionOnMethodReturnType) astNode;
		SingleTypeReference type = (CompletionOnSingleTypeReference) method.returnType;
		this.completionToken = type.token;
		setSourceAndTokenRange(type.sourceStart, type.sourceEnd);
		findTypesAndPackages(this.completionToken, scope.parent, true, true, new ObjectVector());
		if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
			findKeywordsForMember(this.completionToken, method.modifiers);
		}

		if (method.modifiers == ClassFileConstants.AccDefault) {
			SourceTypeBinding enclosingType = scope.enclosingSourceType();
			if (!enclosingType.isAnnotationType()) {
				if (!this.requestor.isIgnored(CompletionProposal.METHOD_DECLARATION)) {
					findMethodDeclarations(
							this.completionToken,
							scope.enclosingSourceType(),
							scope,
							new ObjectVector(),
							null,
							null,
							null,
							false);
				}
				if (!this.requestor.isIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION)) {
					proposeNewMethod(this.completionToken, scope.enclosingSourceType());
				}
			}
		}
	}
	
	private void completionOnParameterizedQualifiedTypeReference(ASTNode astNode, ASTNode astNodeParent, Binding qualifiedBinding, Scope scope) {
		if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
			CompletionOnParameterizedQualifiedTypeReference ref = (CompletionOnParameterizedQualifiedTypeReference) astNode;

			this.insideQualifiedReference = true;

			this.assistNodeIsClass = ref.isClass();
			this.assistNodeIsException = ref.isException();
			this.assistNodeIsInterface = ref.isInterface();
			this.assistNodeIsSuperType = ref.isSuperType();
			this.assistNodeIsExtendedType = assistNodeIsExtendedType(astNode, astNodeParent);
			this.assistNodeIsInterfaceExcludingAnnotation = assistNodeIsInterfaceExcludingAnnotation(astNode, astNodeParent);

			this.completionToken = ref.completionIdentifier;
			long completionPosition = ref.sourcePositions[ref.tokens.length];
			setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);

			if (qualifiedBinding.problemId() == ProblemReasons.NotFound ||
					(((ReferenceBinding)qualifiedBinding).tagBits & TagBits.HasMissingType) != 0) {
				if (this.assistNodeInJavadoc == 0 &&
						(this.requestor.isAllowingRequiredProposals(CompletionProposal.TYPE_REF, CompletionProposal.TYPE_REF))) {
					if(ref.tokens.length == 1) {
						findMemberTypesFromMissingType(
								ref,
								ref.sourcePositions[0],
								scope);
					}
				}
			} else {
				ObjectVector typesFound = new ObjectVector();
				if (this.assistNodeIsException && astNodeParent instanceof TryStatement) {
					findExceptionFromTryStatement(
							this.completionToken,
							(ReferenceBinding)qualifiedBinding,
							scope.enclosingSourceType(),
							(BlockScope)scope,
							typesFound);
				}
				
				checkCancel();
				
				findMemberTypes(
					this.completionToken,
					(ReferenceBinding) qualifiedBinding,
					scope,
					scope.enclosingSourceType(),
					false,
					false,
					typesFound,
					null,
					null,
					null,
					false);
			}
		}
	}

	private boolean assistNodeIsExtendedType(ASTNode astNode, ASTNode astNodeParent) {
		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=99399, don't propose final types for extension.
		if (astNodeParent == null)
			return false;
		if (astNodeParent instanceof TypeDeclaration) {
			TypeDeclaration typeDeclaration = (TypeDeclaration) astNodeParent;
			return (typeDeclaration.superclass == astNode);	
		} else if (astNodeParent instanceof TypeParameter) {
			TypeParameter typeParameter = (TypeParameter) astNodeParent;
			return (typeParameter.type == astNode);
		} else if (astNodeParent instanceof Wildcard) {
			Wildcard wildcard = (Wildcard) astNodeParent;
			return (wildcard.bound == astNode && wildcard.kind == Wildcard.EXTENDS);
		}
		return false;
	}
	
	private boolean assistNodeIsInterfaceExcludingAnnotation(ASTNode astNode, ASTNode astNodeParent) {
		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=310423, don't propose annotations for implements.
		if (astNodeParent == null)
			return false;
		if (astNodeParent instanceof TypeDeclaration) {
			TypeDeclaration typeDeclaration = (TypeDeclaration) astNodeParent;
			TypeReference [] superInterfaces = typeDeclaration.superInterfaces;
			int length = superInterfaces == null ? 0 : superInterfaces.length;
			for (int i = 0; i < length; i++) {
				if (superInterfaces[i] == astNode)
					return true;
			}
		}
		return false;
	}
	
	private boolean assistNodeIsInsideCase(ASTNode astNode, ASTNode astNodeParent) {
		// To find whether we're completing inside the case expression in a 
		// switch case construct (https://bugs.eclipse.org/bugs/show_bug.cgi?id=195346)
		if (astNodeParent instanceof SwitchStatement) {
			CaseStatement[] cases = ((SwitchStatement) astNodeParent).cases;
			for (int i = 0, caseCount = ((SwitchStatement) astNodeParent).caseCount; i < caseCount; i++) {
				CompletionNodeDetector detector = new CompletionNodeDetector(astNode, cases[i]);
				if (detector.containsCompletionNode()) {
					return true;
				}
			}
		}
		return false;
	}

	private void completionOnQualifiedAllocationExpression(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
		setSourceAndTokenRange(astNode.sourceStart, astNode.sourceEnd, false);

		CompletionOnQualifiedAllocationExpression allocExpression =
			(CompletionOnQualifiedAllocationExpression) astNode;
		TypeBinding[] argTypes = computeTypes(allocExpression.arguments);

		ReferenceBinding ref = (ReferenceBinding) qualifiedBinding;
		
		if (ref.problemId() == ProblemReasons.NotFound) {
			findConstructorsFromMissingType(
					allocExpression.type,
					argTypes,
					scope,
					allocExpression);
		} else {
			if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)
					&& ref.isClass()
					&& !ref.isAbstract()) {
					findConstructors(
						ref,
						argTypes,
						scope,
						allocExpression,
						false,
						null,
						null,
						null,
						false);
			}
			
			checkCancel();
			
			if (!this.requestor.isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION)
					&& !ref.isFinal()
					&& !ref.isEnum()){
				findAnonymousType(
					ref,
					argTypes,
					scope,
					allocExpression,
					null,
					null,
					null,
					false);
			}
		}
	}
	
	private void completionOnQualifiedNameReference(ASTNode astNode, ASTNode enclosingNode, Binding qualifiedBinding,
			Scope scope, boolean insideTypeAnnotation) {
		this.insideQualifiedReference = true;
		CompletionOnQualifiedNameReference ref =
			(CompletionOnQualifiedNameReference) astNode;
		this.completionToken = ref.completionIdentifier;
		long completionPosition = ref.sourcePositions[ref.sourcePositions.length - 1];
		this.assistNodeIsInsideCase = assistNodeIsInsideCase(astNode, this.parser.assistNodeParent);

		if (qualifiedBinding.problemId() == ProblemReasons.NotFound) {
			setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
			// complete field members with missing fields type
			// class X {
			//   Missing f;
			//   void foo() {
			//     f.|
			//   }
			// }
			if (this.assistNodeInJavadoc == 0 &&
					(this.requestor.isAllowingRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_REF) ||
							this.requestor.isAllowingRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_REF) ||
							this.requestor.isAllowingRequiredProposals(CompletionProposal.TYPE_REF, CompletionProposal.TYPE_REF))) {
				if(ref.tokens.length == 1) {
					boolean foundSomeFields = findFieldsAndMethodsFromMissingFieldType(ref.tokens[0], scope, ref, insideTypeAnnotation);

					if (!foundSomeFields) {
						
						checkCancel();
						
						findMembersFromMissingType(
								ref.tokens[0],
								ref.sourcePositions[0],
								null,
								scope,
								ref,
								ref.isInsideAnnotationAttribute);
					}
				}
			}
		} else if (qualifiedBinding instanceof VariableBinding) {
			setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
			TypeBinding receiverType = ((VariableBinding) qualifiedBinding).type;
			if (receiverType != null && (receiverType.tagBits & TagBits.HasMissingType) == 0) {
				ObjectVector fieldsFound = new ObjectVector();
				ObjectVector methodsFound = new ObjectVector();

				findFieldsAndMethods(
						this.completionToken,
						receiverType.capture(scope, ref.sourceEnd),
						scope,
						fieldsFound,
						methodsFound,
						ref,
						scope,
						false,
						false,
						null,
						null,
						null,
						false,
						null,
						-1,
						-1);
				
				checkCancel();

				findFieldsAndMethodsFromCastedReceiver(
						enclosingNode,
						qualifiedBinding,
						scope,
						fieldsFound,
						methodsFound,
						ref,
						scope,
						ref);

			} else if (this.assistNodeInJavadoc == 0 &&
					(this.requestor.isAllowingRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_REF) ||
							this.requestor.isAllowingRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_REF))) {
				boolean proposeField = !this.requestor.isIgnored(CompletionProposal.FIELD_REF);
				boolean proposeMethod = !this.requestor.isIgnored(CompletionProposal.METHOD_REF);
				if (proposeField || proposeMethod) {
					if(ref.tokens.length == 1) {
						if (qualifiedBinding instanceof LocalVariableBinding) {
							// complete local variable members with missing variables type
							// class X {
							//   void foo() {
							//     Missing f;
							//     f.|
							//   }
							// }
							LocalVariableBinding localVariableBinding = (LocalVariableBinding) qualifiedBinding;
							findFieldsAndMethodsFromMissingType(
									localVariableBinding.declaration.type,
									localVariableBinding.declaringScope,
									ref,
									scope);
						} else {
							// complete field members with missing fields type
							// class X {
							//   Missing f;
							//   void foo() {
							//     f.|
							//   }
							// }
							findFieldsAndMethodsFromMissingFieldType(ref.tokens[0], scope, ref, insideTypeAnnotation);
						}

					}
				}
			}

		} else if (qualifiedBinding instanceof ReferenceBinding && !(qualifiedBinding instanceof TypeVariableBinding)) {
			boolean isInsideAnnotationAttribute = ref.isInsideAnnotationAttribute;
			ReferenceBinding receiverType = (ReferenceBinding) qualifiedBinding;
			setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);

			findMembers(
					this.completionToken,
					receiverType,
					scope,
					ref,
					isInsideAnnotationAttribute,
					null,
					null,
					null,
					false);

		} else if (qualifiedBinding instanceof PackageBinding) {

			setSourceRange(astNode.sourceStart, (int) completionPosition);
			setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);

			// replace to the end of the completion identifier
			findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
		}
	}
	
	private void completionOnQualifiedTypeReference(ASTNode astNode, ASTNode astNodeParent, Binding qualifiedBinding,
			Scope scope) {
		this.insideQualifiedReference = true;

		CompletionOnQualifiedTypeReference ref =
			(CompletionOnQualifiedTypeReference) astNode;

		this.assistNodeIsClass = ref.isClass();
		this.assistNodeIsException = ref.isException();
		this.assistNodeIsInterface = ref.isInterface();
		this.assistNodeIsConstructor = ref.isConstructorType;
		this.assistNodeIsSuperType = ref.isSuperType();
		this.assistNodeIsExtendedType = assistNodeIsExtendedType(astNode, astNodeParent);
		this.assistNodeIsInterfaceExcludingAnnotation = assistNodeIsInterfaceExcludingAnnotation(astNode, astNodeParent);
		this.assistNodeIsInsideCase = assistNodeIsInsideCase(astNode, astNodeParent);
		
		this.completionToken = ref.completionIdentifier;
		long completionPosition = ref.sourcePositions[ref.tokens.length];

		// get the source positions of the completion identifier
		if (qualifiedBinding.problemId() == ProblemReasons.NotFound) {
			setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
			if (this.assistNodeInJavadoc == 0 &&
					(this.requestor.isAllowingRequiredProposals(CompletionProposal.TYPE_REF, CompletionProposal.TYPE_REF))) {
				if(ref.tokens.length == 1) {
					findMemberTypesFromMissingType(
							ref.tokens[0],
							ref.sourcePositions[0],
							scope);
				}
			}
		} else if (qualifiedBinding instanceof ReferenceBinding && !(qualifiedBinding instanceof TypeVariableBinding)) {
			if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
				setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);

				ObjectVector typesFound = new ObjectVector();

				if (this.assistNodeIsException && astNodeParent instanceof TryStatement) {
					findExceptionFromTryStatement(
							this.completionToken,
							(ReferenceBinding)qualifiedBinding,
							scope.enclosingSourceType(),
							(BlockScope)scope,
							typesFound);
				}
				
				checkCancel();

				findMemberTypes(
					this.completionToken,
					(ReferenceBinding) qualifiedBinding,
					scope,
					scope.enclosingSourceType(),
					false,
					false,
					typesFound,
					null,
					null,
					null,
					false);
			}
		} else if (qualifiedBinding instanceof PackageBinding) {

			setSourceRange(astNode.sourceStart, (int) completionPosition);
			setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
			// replace to the end of the completion identifier
			findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
		}
	}
	
	private void completionOnSingleNameReference(ASTNode astNode, ASTNode astNodeParent, Scope scope,
			boolean insideTypeAnnotation) {
		CompletionOnSingleNameReference singleNameReference = (CompletionOnSingleNameReference) astNode;
		this.completionToken = singleNameReference.token;
		SwitchStatement switchStatement = astNodeParent instanceof SwitchStatement ? (SwitchStatement) astNodeParent : null;
		this.assistNodeIsInsideCase = assistNodeIsInsideCase(astNode, astNodeParent);
		if (switchStatement != null
				&& switchStatement.expression.resolvedType != null
				&& switchStatement.expression.resolvedType.isEnum()) {
			if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
				this.assistNodeIsEnum = true;
				findEnumConstantsFromSwithStatement(this.completionToken, (SwitchStatement) astNodeParent);
			}
		} else if (this.expectedTypesPtr > -1 && this.expectedTypes[0].isAnnotationType()) {
			findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
		} else {
			if (this.expectedTypesPtr > -1) {
				this.assistNodeIsEnum = true;
				done : for (int i = 0; i <= this.expectedTypesPtr; i++) {
					if (!this.expectedTypes[i].isEnum()) {
						this.assistNodeIsEnum = false;
						break done;
					}
				}

			}
			if (scope instanceof BlockScope && !this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
				char[][] alreadyDefinedName = computeAlreadyDefinedName((BlockScope)scope, singleNameReference);

				findUnresolvedReference(
						singleNameReference.sourceStart,
						singleNameReference.sourceEnd,
						(BlockScope)scope,
						alreadyDefinedName);
			}
			
			checkCancel();
			
			findVariablesAndMethods(
				this.completionToken,
				scope,
				singleNameReference,
				scope,
				insideTypeAnnotation,
				singleNameReference.isInsideAnnotationAttribute);
			
			checkCancel();
			
			// can be the start of a qualified type name
			findTypesAndPackages(this.completionToken, scope, true, false, new ObjectVector());
			if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
				if (this.completionToken != null && this.completionToken.length != 0) {
					findKeywords(this.completionToken, singleNameReference.possibleKeywords, false, false);
				} else {
					findTrueOrFalseKeywords(singleNameReference.possibleKeywords);
				}
			}
			if (singleNameReference.canBeExplicitConstructor && !this.requestor.isIgnored(CompletionProposal.METHOD_REF)){
				if (CharOperation.prefixEquals(this.completionToken, Keywords.THIS, false)) {
					ReferenceBinding ref = scope.enclosingSourceType();
					findExplicitConstructors(Keywords.THIS, ref, (MethodScope)scope, singleNameReference);
				} else if (CharOperation.prefixEquals(this.completionToken, Keywords.SUPER, false)) {
					ReferenceBinding ref = scope.enclosingSourceType();
					findExplicitConstructors(Keywords.SUPER, ref.superclass(), (MethodScope)scope, singleNameReference);
				}
			}
		}
	}
	
	private void completionOnSingleTypeReference(ASTNode astNode, ASTNode astNodeParent, Binding qualifiedBinding, Scope scope) {
		CompletionOnSingleTypeReference singleRef = (CompletionOnSingleTypeReference) astNode;

		this.completionToken = singleRef.token;

		this.assistNodeIsClass = singleRef.isClass();
		this.assistNodeIsException = singleRef.isException();
		this.assistNodeIsInterface = singleRef.isInterface();
		this.assistNodeIsConstructor = singleRef.isConstructorType;
		this.assistNodeIsSuperType = singleRef.isSuperType();
		this.assistNodeIsExtendedType = assistNodeIsExtendedType(astNode, astNodeParent);
		this.assistNodeIsInterfaceExcludingAnnotation = assistNodeIsInterfaceExcludingAnnotation(astNode, astNodeParent);
		this.assistNodeIsInsideCase = assistNodeIsInsideCase(astNode, astNodeParent);
		
		// can be the start of a qualified type name
		if (qualifiedBinding == null) {
			if (this.completionToken.length == 0 &&
					(astNodeParent instanceof ParameterizedSingleTypeReference ||
							astNodeParent instanceof ParameterizedQualifiedTypeReference)) {
				this.setSourceAndTokenRange(astNode.sourceStart, astNode.sourceStart - 1, false);

				findParameterizedType((TypeReference)astNodeParent, scope);
			} else {
				ObjectVector typesFound = new ObjectVector();
				if (this.assistNodeIsException && astNodeParent instanceof TryStatement) {
					findExceptionFromTryStatement(
							this.completionToken,
							null,
							scope.enclosingSourceType(),
							(BlockScope)scope,
							typesFound);
				}
				
				checkCancel();
				
				findTypesAndPackages(this.completionToken, scope, this.assistNodeIsConstructor, false, typesFound);
			}
		} else if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
			findMemberTypes(
				this.completionToken,
				(ReferenceBinding) qualifiedBinding,
				scope,
				scope.enclosingSourceType(),
				false,
				false,
				false,
				false,
				!this.assistNodeIsConstructor,
				null,
				new ObjectVector(),
				null,
				null,
				null,
				false);
		}
	}

	private char[][] computeAlreadyDefinedName(
			BlockScope scope,
			InvocationSite invocationSite) {
		ArrayList result = new ArrayList();

		boolean staticsOnly = false;

		Scope currentScope = scope;

		done1 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found

			switch (currentScope.kind) {

				case Scope.METHOD_SCOPE :
					// handle the error case inside an explicit constructor call (see MethodScope>>findField)
					MethodScope methodScope = (MethodScope) currentScope;
					staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;

				//$FALL-THROUGH$
				case Scope.BLOCK_SCOPE :
					BlockScope blockScope = (BlockScope) currentScope;

					next : for (int i = 0, length = blockScope.locals.length; i < length; i++) {
						LocalVariableBinding local = blockScope.locals[i];

						if (local == null)
							break next;

						if (local.isSecret())
							continue next;

						result.add(local.name);
					}
					break;

				case Scope.CLASS_SCOPE :
					ClassScope classScope = (ClassScope) currentScope;
					SourceTypeBinding enclosingType = classScope.referenceContext.binding;
					computeAlreadyDefinedName(
							enclosingType,
							classScope,
							staticsOnly,
							invocationSite,
							result);
					staticsOnly |= enclosingType.isStatic();
					break;

				case Scope.COMPILATION_UNIT_SCOPE :
					break done1;
			}
			currentScope = currentScope.parent;
		}

		if (result.size() == 0) return CharOperation.NO_CHAR_CHAR;

		return (char[][])result.toArray(new char[result.size()][]);
	}

	private void computeAlreadyDefinedName(
			FieldBinding[] fields,
			Scope scope,
			boolean onlyStaticFields,
			ReferenceBinding receiverType,
			InvocationSite invocationSite,
			ArrayList result) {

		next : for (int f = fields.length; --f >= 0;) {
			FieldBinding field = fields[f];

			if (field.isSynthetic()) continue next;

			if (onlyStaticFields && !field.isStatic()) continue next;

			if (!field.canBeSeenBy(receiverType, invocationSite, scope)) continue next;

			result.add(field.name);
		}
	}

	private void computeAlreadyDefinedName(
			SourceTypeBinding receiverType,
			ClassScope scope,
			boolean onlyStaticFields,
			InvocationSite invocationSite,
			ArrayList result) {

		ReferenceBinding currentType = receiverType;
		ReferenceBinding[] interfacesToVisit = null;
		int nextPosition = 0;
		do {
			ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
			if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
				if (interfacesToVisit == null) {
					interfacesToVisit = itsInterfaces;
					nextPosition = interfacesToVisit.length;
				} else {
					int itsLength = itsInterfaces.length;
					if (nextPosition + itsLength >= interfacesToVisit.length)
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
					nextInterface : for (int a = 0; a < itsLength; a++) {
						ReferenceBinding next = itsInterfaces[a];
						for (int b = 0; b < nextPosition; b++)
							if (next == interfacesToVisit[b]) continue nextInterface;
						interfacesToVisit[nextPosition++] = next;
					}
				}
			}

			FieldBinding[] fields = currentType.availableFields();
			if(fields != null && fields.length > 0) {
				computeAlreadyDefinedName(
					fields,
					scope,
					onlyStaticFields,
					receiverType,
					invocationSite,
					result);
			}
			currentType = currentType.superclass();
		} while ( currentType != null);

		if (interfacesToVisit != null) {
			for (int i = 0; i < nextPosition; i++) {
				ReferenceBinding anInterface = interfacesToVisit[i];
				FieldBinding[] fields = anInterface.availableFields();
				if(fields !=  null) {
					computeAlreadyDefinedName(
						fields,
						scope,
						onlyStaticFields,
						receiverType,
						invocationSite,
						result);
				}

				ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
				if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
					int itsLength = itsInterfaces.length;
					if (nextPosition + itsLength >= interfacesToVisit.length)
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
					nextInterface : for (int a = 0; a < itsLength; a++) {
						ReferenceBinding next = itsInterfaces[a];
						for (int b = 0; b < nextPosition; b++)
							if (next == interfacesToVisit[b]) continue nextInterface;
						interfacesToVisit[nextPosition++] = next;
					}
				}
			}
		}
	}

	int computeBaseRelevance(){
		return R_DEFAULT;
	}

	private void computeExpectedTypes(ASTNode parent, ASTNode node, Scope scope){

		// default filter
		this.expectedTypesFilter = SUBTYPE;
		this.hasJavaLangObjectAsExpectedType = false;

		// find types from parent
		if(parent instanceof AbstractVariableDeclaration && !(parent instanceof TypeParameter)) {
			AbstractVariableDeclaration variable = (AbstractVariableDeclaration)parent;
			TypeBinding binding = variable.type.resolvedType;
			if(binding != null) {
				if(!(variable.initialization instanceof ArrayInitializer)) {
					addExpectedType(binding, scope);
				}
			}
		} else if(parent instanceof Assignment) {
			TypeBinding binding = ((Assignment)parent).lhs.resolvedType;
			if(binding != null) {
				addExpectedType(binding, scope);
			}
		} else if(parent instanceof ReturnStatement) {
			if(scope.methodScope().referenceContext instanceof AbstractMethodDeclaration) {
				MethodBinding methodBinding = ((AbstractMethodDeclaration) scope.methodScope().referenceContext).binding;
				TypeBinding binding = methodBinding  == null ? null : methodBinding.returnType;
				if(binding != null) {
					addExpectedType(binding, scope);
				}
			}
		} else if(parent instanceof CastExpression) {
			Expression e = ((CastExpression)parent).type;
			TypeBinding binding = e.resolvedType;
			if(binding != null){
				addExpectedType(binding, scope);
				this.expectedTypesFilter = SUBTYPE | SUPERTYPE;
			}
		} else if(parent instanceof MessageSend) {
			MessageSend messageSend = (MessageSend) parent;

			if(messageSend.actualReceiverType instanceof ReferenceBinding) {
				ReferenceBinding binding = (ReferenceBinding)messageSend.actualReceiverType;
				boolean isStatic = messageSend.receiver.isTypeReference();

				while(binding != null) {
					computeExpectedTypesForMessageSend(
						binding,
						messageSend.selector,
						messageSend.arguments,
						(ReferenceBinding)messageSend.actualReceiverType,
						scope,
						messageSend,
						isStatic);
					computeExpectedTypesForMessageSendForInterface(
						binding,
						messageSend.selector,
						messageSend.arguments,
						(ReferenceBinding)messageSend.actualReceiverType,
						scope,
						messageSend,
						isStatic);
					binding = binding.superclass();
				}
			}
		} else if(parent instanceof AllocationExpression) {
			AllocationExpression allocationExpression = (AllocationExpression) parent;

			ReferenceBinding binding = (ReferenceBinding)allocationExpression.type.resolvedType;

			if(binding != null) {
				computeExpectedTypesForAllocationExpression(
					binding,
					allocationExpression.arguments,
					scope,
					allocationExpression);
			}
		} else if(parent instanceof OperatorExpression) {
			int operator = (parent.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT;
			if(parent instanceof ConditionalExpression) {
				// for future use
			} else if(parent instanceof InstanceOfExpression) {
				InstanceOfExpression e = (InstanceOfExpression) parent;
				TypeBinding binding = e.expression.resolvedType;
				if(binding != null){
					addExpectedType(binding, scope);
					this.expectedTypesFilter = SUBTYPE | SUPERTYPE;
				}
			} else if(parent instanceof BinaryExpression) {
				BinaryExpression binaryExpression = (BinaryExpression) parent;
				switch(operator) {
					case OperatorIds.EQUAL_EQUAL :
						// expected type is not relevant in this case
						TypeBinding binding = binaryExpression.left.resolvedType;
						if (binding != null) {
							addExpectedType(binding, scope);
							this.expectedTypesFilter = SUBTYPE | SUPERTYPE;
						}
						break;
					case OperatorIds.PLUS :
						addExpectedType(TypeBinding.SHORT, scope);
						addExpectedType(TypeBinding.INT, scope);
						addExpectedType(TypeBinding.LONG, scope);
						addExpectedType(TypeBinding.FLOAT, scope);
						addExpectedType(TypeBinding.DOUBLE, scope);
						addExpectedType(TypeBinding.CHAR, scope);
						addExpectedType(TypeBinding.BYTE, scope);
						addExpectedType(scope.getJavaLangString(), scope);
						break;
					case OperatorIds.AND_AND :
					case OperatorIds.OR_OR :
					case OperatorIds.XOR :
						addExpectedType(TypeBinding.BOOLEAN, scope);
						break;
					default :
						addExpectedType(TypeBinding.SHORT, scope);
						addExpectedType(TypeBinding.INT, scope);
						addExpectedType(TypeBinding.LONG, scope);
						addExpectedType(TypeBinding.FLOAT, scope);
						addExpectedType(TypeBinding.DOUBLE, scope);
						addExpectedType(TypeBinding.CHAR, scope);
						addExpectedType(TypeBinding.BYTE, scope);
						break;
				}
				if(operator == OperatorIds.LESS) {
					if(binaryExpression.left instanceof SingleNameReference){
						SingleNameReference name = (SingleNameReference) binaryExpression.left;
						Binding b = scope.getBinding(name.token, Binding.VARIABLE | Binding.TYPE, name, false);
						if(b instanceof ReferenceBinding) {
							TypeVariableBinding[] typeVariableBindings =((ReferenceBinding)b).typeVariables();
							if(typeVariableBindings != null && typeVariableBindings.length > 0) {
								addExpectedType(typeVariableBindings[0].firstBound, scope);
							}

						}
					}
				}
			} else if(parent instanceof UnaryExpression) {
				switch(operator) {
					case OperatorIds.NOT :
						addExpectedType(TypeBinding.BOOLEAN, scope);
						break;
					case OperatorIds.TWIDDLE :
						addExpectedType(TypeBinding.SHORT, scope);
						addExpectedType(TypeBinding.INT, scope);
						addExpectedType(TypeBinding.LONG, scope);
						addExpectedType(TypeBinding.CHAR, scope);
						addExpectedType(TypeBinding.BYTE, scope);
						break;
					case OperatorIds.PLUS :
					case OperatorIds.MINUS :
					case OperatorIds.PLUS_PLUS :
					case OperatorIds.MINUS_MINUS :
						addExpectedType(TypeBinding.SHORT, scope);
						addExpectedType(TypeBinding.INT, scope);
						addExpectedType(TypeBinding.LONG, scope);
						addExpectedType(TypeBinding.FLOAT, scope);
						addExpectedType(TypeBinding.DOUBLE, scope);
						addExpectedType(TypeBinding.CHAR, scope);
						addExpectedType(TypeBinding.BYTE, scope);
						break;
				}
			}
		} else if(parent instanceof ArrayReference) {
			addExpectedType(TypeBinding.SHORT, scope);
			addExpectedType(TypeBinding.INT, scope);
			addExpectedType(TypeBinding.LONG, scope);
		} else if(parent instanceof ParameterizedSingleTypeReference) {
			ParameterizedSingleTypeReference ref = (ParameterizedSingleTypeReference) parent;
			TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables();
			int length = ref.typeArguments == null ? 0 : ref.typeArguments.length;
			if(typeVariables != null && typeVariables.length >= length) {
				int index = length - 1;
				while(index > -1 && ref.typeArguments[index] != node) index--;

				TypeBinding bound = typeVariables[index].firstBound;
				addExpectedType(bound == null ? scope.getJavaLangObject() : bound, scope);
			}
		} else if(parent instanceof ParameterizedQualifiedTypeReference) {
			ParameterizedQualifiedTypeReference ref = (ParameterizedQualifiedTypeReference) parent;
			TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables();
			TypeReference[][] arguments = ref.typeArguments;
			if(typeVariables != null) {
				int iLength = arguments == null ? 0 : arguments.length;
				done: for (int i = 0; i < iLength; i++) {
					int jLength = arguments[i] == null ? 0 : arguments[i].length;
					for (int j = 0; j < jLength; j++) {
						if(arguments[i][j] == node && typeVariables.length > j) {
							TypeBinding bound = typeVariables[j].firstBound;
							addExpectedType(bound == null ? scope.getJavaLangObject() : bound, scope);
							break done;
						}
					}
				}
			}
		} else if(parent instanceof MemberValuePair) {
			MemberValuePair memberValuePair = (MemberValuePair) parent;
			if(memberValuePair.binding != null) {
				addExpectedType(memberValuePair.binding.returnType, scope);
			}
		} else if (parent instanceof NormalAnnotation) {
			NormalAnnotation annotation = (NormalAnnotation) parent;
			MemberValuePair[] memberValuePairs = annotation.memberValuePairs();
			if(memberValuePairs == null || memberValuePairs.length == 0) {
				if(annotation.resolvedType instanceof ReferenceBinding) {
					MethodBinding[] methodBindings =
						((ReferenceBinding)annotation.resolvedType).availableMethods();
					if (methodBindings != null &&
							methodBindings.length > 0 &&
							CharOperation.equals(methodBindings[0].selector, VALUE)) {
						boolean canBeSingleMemberAnnotation = true;
						done : for (int i = 1; i < methodBindings.length; i++) {
							if((methodBindings[i].modifiers & ClassFileConstants.AccAnnotationDefault) == 0) {
								canBeSingleMemberAnnotation = false;
								break done;
							}
						}
						if (canBeSingleMemberAnnotation) {
							this.assistNodeCanBeSingleMemberAnnotation = canBeSingleMemberAnnotation;
							addExpectedType(methodBindings[0].returnType, scope);
						}
					}
				}
			}
		} else if (parent instanceof TryStatement) {
			boolean isException = false;
			if (node instanceof CompletionOnSingleTypeReference) {
				isException = ((CompletionOnSingleTypeReference)node).isException();
			} else if (node instanceof CompletionOnQualifiedTypeReference) {
				isException = ((CompletionOnQualifiedTypeReference)node).isException();
			} else if (node instanceof CompletionOnParameterizedQualifiedTypeReference) {
				isException = ((CompletionOnParameterizedQualifiedTypeReference)node).isException();
			}
			if (isException) {
				ThrownExceptionFinder thrownExceptionFinder = new ThrownExceptionFinder();
				ReferenceBinding[] bindings = thrownExceptionFinder.find((TryStatement) parent, (BlockScope)scope);
				if (bindings != null && bindings.length > 0) {
					for (int i = 0; i < bindings.length; i++) {
						addExpectedType(bindings[i], scope);
					}
					this.expectedTypesFilter = SUPERTYPE;
				}
			}
		} else if (parent instanceof SwitchStatement) {
			SwitchStatement switchStatement = (SwitchStatement) parent;
			if (switchStatement.expression != null &&
					switchStatement.expression.resolvedType != null) {
				addExpectedType(switchStatement.expression.resolvedType, scope);
			}
		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=253008, flag boolean as the expected
		// type if we are completing inside if(), for (; ;), while() and do while()
		} else if (parent instanceof WhileStatement) {  // covers both while and do-while loops
			addExpectedType(TypeBinding.BOOLEAN, scope);
		} else if (parent instanceof IfStatement) {  
			addExpectedType(TypeBinding.BOOLEAN, scope);
		} else if (parent instanceof AssertStatement) {
			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=274466
			// If the assertExpression is same as the node , then the assistNode is the conditional part of the assert statement
			AssertStatement assertStatement = (AssertStatement) parent;
			if (assertStatement.assertExpression == node) {
				addExpectedType(TypeBinding.BOOLEAN, scope);
			}
		} else if (parent instanceof ForStatement) {   // astNodeParent set to ForStatement only for the condition  
			addExpectedType(TypeBinding.BOOLEAN, scope);

		// Expected types for javadoc
		} else if (parent instanceof Javadoc) {
			if (scope.kind == Scope.METHOD_SCOPE) {
				MethodScope methodScope = (MethodScope) scope;
				AbstractMethodDeclaration methodDecl = methodScope.referenceMethod();
				if (methodDecl != null && methodDecl.binding != null) {
					ReferenceBinding[] exceptions = methodDecl.binding.thrownExceptions;
					if (exceptions != null) {
						for (int i = 0; i < exceptions.length; i++) {
							addExpectedType(exceptions[i], scope);
						}
					}
				}
			}
		}

		if(this.expectedTypesPtr + 1 != this.expectedTypes.length) {
			System.arraycopy(this.expectedTypes, 0, this.expectedTypes = new TypeBinding[this.expectedTypesPtr + 1], 0, this.expectedTypesPtr + 1);
		}
	}

	private void computeExpectedTypesForAllocationExpression(
		ReferenceBinding binding,
		Expression[] arguments,
		Scope scope,
		InvocationSite invocationSite) {

		MethodBinding[] methods = binding.availableMethods();
		nextMethod : for (int i = 0; i < methods.length; i++) {
			MethodBinding method = methods[i];

			if (!method.isConstructor()) continue nextMethod;

			if (method.isSynthetic()) continue nextMethod;

			if (this.options.checkVisibility && !method.canBeSeenBy(invocationSite, scope)) continue nextMethod;

			TypeBinding[] parameters = method.parameters;
			if(parameters.length < arguments.length)
				continue nextMethod;

			int length = arguments.length - 1;

			for (int j = 0; j < length; j++) {
				Expression argument = arguments[j];
				TypeBinding argType = argument.resolvedType;
				if(argType != null && !argType.isCompatibleWith(parameters[j]))
					continue nextMethod;
			}

			TypeBinding expectedType = method.parameters[arguments.length - 1];
			if(expectedType != null) {
				addExpectedType(expectedType, scope);
			}
		}
	}
	private void computeExpectedTypesForMessageSend(
		ReferenceBinding binding,
		char[] selector,
		Expression[] arguments,
		ReferenceBinding receiverType,
		Scope scope,
		InvocationSite invocationSite,
		boolean isStatic) {

		MethodBinding[] methods = binding.availableMethods();
		nextMethod : for (int i = 0; i < methods.length; i++) {
			MethodBinding method = methods[i];

			if (method.isSynthetic()) continue nextMethod;

			if (method.isDefaultAbstract())	continue nextMethod;

			if (method.isConstructor()) continue nextMethod;

			if (isStatic && !method.isStatic()) continue nextMethod;

			if (this.options.checkVisibility && !method.canBeSeenBy(receiverType, invocationSite, scope)) continue nextMethod;

			if(!CharOperation.equals(method.selector, selector)) continue nextMethod;

			TypeBinding[] parameters = method.parameters;
			if(parameters.length < arguments.length)
				continue nextMethod;

			int length = arguments.length - 1;

			for (int j = 0; j < length; j++) {
				Expression argument = arguments[j];
				TypeBinding argType = argument.resolvedType;
				if(argType != null && !argType.isCompatibleWith(parameters[j]))
					continue nextMethod;
			}

			TypeBinding expectedType = method.parameters[arguments.length - 1];
			if(expectedType != null) {
				addExpectedType(expectedType, scope);
			}
		}
	}
	private void computeExpectedTypesForMessageSendForInterface(
		ReferenceBinding binding,
		char[] selector,
		Expression[] arguments,
		ReferenceBinding receiverType,
		Scope scope,
		InvocationSite invocationSite,
		boolean isStatic) {

		ReferenceBinding[] itsInterfaces = binding.superInterfaces();
		if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
			ReferenceBinding[] interfacesToVisit = itsInterfaces;
			int nextPosition = interfacesToVisit.length;

			for (int i = 0; i < nextPosition; i++) {
				ReferenceBinding currentType = interfacesToVisit[i];
				computeExpectedTypesForMessageSend(
					currentType,
					selector,
					arguments,
					receiverType,
					scope,
					invocationSite,
					isStatic);

				if ((itsInterfaces = currentType.superInterfaces()) != Binding.NO_SUPERINTERFACES) {
					int itsLength = itsInterfaces.length;
					if (nextPosition + itsLength >= interfacesToVisit.length)
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
					nextInterface : for (int a = 0; a < itsLength; a++) {
						ReferenceBinding next = itsInterfaces[a];
						for (int b = 0; b < nextPosition; b++)
							if (next == interfacesToVisit[b]) continue nextInterface;
						interfacesToVisit[nextPosition++] = next;
					}
				}
			}
		}
	}

	private Scope computeForbiddenBindings(ASTNode astNode, ASTNode astNodeParent, Scope scope) {
		this.forbbidenBindingsFilter = NONE;
		if(scope instanceof ClassScope) {
			TypeDeclaration typeDeclaration = ((ClassScope)scope).referenceContext;
			if(typeDeclaration.superclass == astNode) {
				addForbiddenBindings(typeDeclaration.binding);
				addForbiddenBindingsForMemberTypes(typeDeclaration);
				return scope.parent;
			}
			TypeReference[] superInterfaces = typeDeclaration.superInterfaces;
			int length = superInterfaces == null ? 0 : superInterfaces.length;
			int astNodeIndex = -1;
			for (int i = 0; i < length; i++) {
				if(superInterfaces[i] == astNode) {
					addForbiddenBindings(typeDeclaration.binding);
					addForbiddenBindingsForMemberTypes(typeDeclaration);
					astNodeIndex = i;
					break;
				}
			}
			if (astNodeIndex >= 0) {
				// Need to loop only up to astNodeIndex as the rest will be undefined.
				for (int i = 0; i < astNodeIndex; i++) {
					addForbiddenBindings(superInterfaces[i].resolvedType);
				}
				return scope.parent;
			}
		} else {
			if (astNodeParent != null && astNodeParent instanceof TryStatement) {
				boolean isException = false;
				if (astNode instanceof CompletionOnSingleTypeReference) {
					isException = ((CompletionOnSingleTypeReference)astNode).isException();
				} else if (astNode instanceof CompletionOnQualifiedTypeReference) {
					isException = ((CompletionOnQualifiedTypeReference)astNode).isException();
				} else if (astNode instanceof CompletionOnParameterizedQualifiedTypeReference) {
					isException = ((CompletionOnParameterizedQualifiedTypeReference)astNode).isException();
				}
				if (isException) {
					Argument[] catchArguments = ((TryStatement) astNodeParent).catchArguments;
					int length = catchArguments == null ? 0 : catchArguments.length;
					for (int i = 0; i < length; i++) {
						TypeBinding caughtException = catchArguments[i].type.resolvedType;
						if (caughtException != null) {
							addForbiddenBindings(caughtException);
							this.knownTypes.put(CharOperation.concat(caughtException.qualifiedPackageName(), caughtException.qualifiedSourceName(), '.'), KNOWN_TYPE_WITH_KNOWN_CONSTRUCTORS);
						}
					}
					this.forbbidenBindingsFilter = SUBTYPE;
				}
			}
		}
//		else if(scope instanceof MethodScope) {
//			MethodScope methodScope = (MethodScope) scope;
//			if(methodScope.insideTypeAnnotation) {
//				return methodScope.parent.parent;
//			}
//		}
		return scope;
	}

	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=270437
	private void addForbiddenBindingsForMemberTypes(TypeDeclaration typeDeclaration) {
		TypeDeclaration[] memberTypes = typeDeclaration.memberTypes;
		int memberTypesLen = memberTypes == null ? 0 : memberTypes.length;
		for (int i = 0; i < memberTypesLen; i++) {
			addForbiddenBindings(memberTypes[i].binding);
			addForbiddenBindingsForMemberTypes(memberTypes[i]);
		}
	}

	private char[] computePrefix(SourceTypeBinding declarationType, SourceTypeBinding invocationType, boolean isStatic){

		StringBuffer completion = new StringBuffer(10);

		if (isStatic) {
			completion.append(declarationType.sourceName());

		} else if (declarationType == invocationType) {
			completion.append(THIS);

		} else {

			if (!declarationType.isNestedType()) {

				completion.append(declarationType.sourceName());
				completion.append('.');
				completion.append(THIS);

			} else if (!declarationType.isAnonymousType()) {

				completion.append(declarationType.sourceName());
				completion.append('.');
				completion.append(THIS);

			}
		}

		return completion.toString().toCharArray();
	}

	private int computeRelevanceForAnnotation(){
		if(this.assistNodeIsAnnotation) {
			return R_ANNOTATION;
		}
		return 0;
	}

	private int computeRelevanceForAnnotationTarget(TypeBinding typeBinding){
		if (this.assistNodeIsAnnotation &&
				(this.targetedElement & TagBits.AnnotationTargetMASK) != 0) {
			long target = typeBinding.getAnnotationTagBits() & TagBits.AnnotationTargetMASK;
			if(target == 0 || (target & this.targetedElement) != 0) {
				return R_TARGET;
			}
		}
		return 0;
	}
	int computeRelevanceForCaseMatching(char[] token, char[] proposalName){
		if (this.options.camelCaseMatch) {
			if(CharOperation.equals(token, proposalName, true /* do not ignore case */)) {
				return R_CASE + R_EXACT_NAME;
			} else if (CharOperation.prefixEquals(token, proposalName, true /* do not ignore case */)) {
				return R_CASE;
			} else if (CharOperation.camelCaseMatch(token, proposalName)){
				return R_CAMEL_CASE;
			} else if(CharOperation.equals(token, proposalName, false /* ignore case */)) {
				return R_EXACT_NAME;
			}
		} else if (CharOperation.prefixEquals(token, proposalName, true /* do not ignore case */)) {
			if(CharOperation.equals(token, proposalName, true /* do not ignore case */)) {
				return R_CASE + R_EXACT_NAME;
			} else {
				return R_CASE;
			}
		} else if(CharOperation.equals(token, proposalName, false /* ignore case */)) {
			return R_EXACT_NAME;
		}
		return 0;
	}

	private int computeRelevanceForClass(){
		if(this.assistNodeIsClass) {
			return R_CLASS;
		}
		return 0;
	}

	private int computeRelevanceForEnum(){
		if(this.assistNodeIsEnum) {
			return R_ENUM;
		}
		return 0;
	}

	private int computeRelevanceForEnumConstant(TypeBinding proposalType){
		if(this.assistNodeIsEnum &&
				proposalType != null &&
				this.expectedTypes != null) {
			for (int i = 0; i <= this.expectedTypesPtr; i++) {
				if (proposalType.isEnum() &&
						proposalType == this.expectedTypes[i]) {
					return R_ENUM + R_ENUM_CONSTANT;
				}

			}
		}
		return 0;
	}

	private int computeRelevanceForException(){
		if (this.assistNodeIsException) {
			return R_EXCEPTION;
		}
		return 0;
	}

	private int computeRelevanceForException(char[] proposalName){

		if((this.assistNodeIsException || (this.assistNodeInJavadoc & CompletionOnJavadoc.EXCEPTION) != 0 )&&
			(CharOperation.match(EXCEPTION_PATTERN, proposalName, false) ||
			CharOperation.match(ERROR_PATTERN, proposalName, false))) {
			return R_EXCEPTION;
		}
		return 0;
	}

	private int computeRelevanceForExpectingType(char[] packageName, char[] typeName){
		if(this.expectedTypes != null) {
			for (int i = 0; i <= this.expectedTypesPtr; i++) {
				if(CharOperation.equals(this.expectedTypes[i].qualifiedPackageName(), packageName) &&
					CharOperation.equals(this.expectedTypes[i].qualifiedSourceName(), typeName)) {
					return R_EXACT_EXPECTED_TYPE;
				}
			}
			if(this.hasJavaLangObjectAsExpectedType) {
				return R_EXPECTED_TYPE;
			}
		}
		return 0;
	}

	private int computeRelevanceForExpectingType(TypeBinding proposalType){
		if(this.expectedTypes != null && proposalType != null) {
			int relevance = 0;
			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=271296
			// If there is at least one expected type, then void proposal types attract a degraded relevance.  
			if (proposalType == TypeBinding.VOID && this.expectedTypesPtr >=0) {
				return R_VOID;
			}	
			for (int i = 0; i <= this.expectedTypesPtr; i++) {
				if((this.expectedTypesFilter & SUBTYPE) != 0
						&& proposalType.isCompatibleWith(this.expectedTypes[i])) {

					if(CharOperation.equals(this.expectedTypes[i].qualifiedPackageName(), proposalType.qualifiedPackageName()) &&
							CharOperation.equals(this.expectedTypes[i].qualifiedSourceName(), proposalType.qualifiedSourceName())) {
						return R_EXACT_EXPECTED_TYPE;
					}

					relevance = R_EXPECTED_TYPE;
				}
				if((this.expectedTypesFilter & SUPERTYPE) != 0
						&& this.expectedTypes[i].isCompatibleWith(proposalType)) {

					if(CharOperation.equals(this.expectedTypes[i].qualifiedPackageName(), proposalType.qualifiedPackageName()) &&
							CharOperation.equals(this.expectedTypes[i].qualifiedSourceName(), proposalType.qualifiedSourceName())) {
						return R_EXACT_EXPECTED_TYPE;
					}

					relevance = R_EXPECTED_TYPE;
				}
				// Bug 84720 - [1.5][assist] proposal ranking by return value should consider auto(un)boxing
				// Just ensuring that the unitScope is not null, even though it's an unlikely case.
				if (this.unitScope != null && this.unitScope.isBoxingCompatibleWith(proposalType, this.expectedTypes[i])) {
					relevance = R_EXPECTED_TYPE;
				}
			}
			return relevance;
		}
		return 0;
	}

	private int computeRelevanceForInheritance(ReferenceBinding receiverType, ReferenceBinding declaringClass) {
		if (receiverType == declaringClass) return R_NON_INHERITED;
		return 0;
	}

	int computeRelevanceForInterestingProposal(){
		return computeRelevanceForInterestingProposal(null);
	}

	private int computeRelevanceForInterestingProposal(Binding binding){
		if(this.uninterestingBindings != null) {
			for (int i = 0; i <= this.uninterestingBindingsPtr; i++) {
				if(this.uninterestingBindings[i] == binding) {
					return 0;
				}
			}
		}
		return R_INTERESTING;
	}

	private int computeRelevanceForInterface(){
		if(this.assistNodeIsInterface) {
			return R_INTERFACE;
		}
		return 0;
	}

	private int computeRelevanceForMissingElements(boolean hasProblems) {
		if (!hasProblems) {
			return R_NO_PROBLEMS;
		}
		return 0;
	}
	int computeRelevanceForQualification(boolean prefixRequired) {
		if(!prefixRequired && !this.insideQualifiedReference) {
			return R_UNQUALIFIED;
		}

		if(prefixRequired && this.insideQualifiedReference) {
			return R_QUALIFIED;
		}
		return 0;
	}

	int computeRelevanceForResolution(){
		return computeRelevanceForResolution(true);
	}

	int computeRelevanceForResolution(boolean isResolved){
		if (isResolved) {
			return R_RESOLVED;
		}
		return 0;
	}

	int computeRelevanceForRestrictions(int accessRuleKind) {
		if(accessRuleKind == IAccessRule.K_ACCESSIBLE) {
			return R_NON_RESTRICTED;
		}
		return 0;
	}

	private int computeRelevanceForStatic(boolean onlyStatic, boolean isStatic) {
		if(this.insideQualifiedReference && !onlyStatic && !isStatic) {
			return R_NON_STATIC;
		}
		return 0;
	}
	
	private int computeRelevanceForFinal(boolean onlyFinal, boolean isFinal) {
		if (onlyFinal && isFinal) {
			return R_FINAL;
		}
		return 0;
	}

	private long computeTargetedElement(CompletionOnAnnotationOfType fakeNode) {
		ASTNode annotatedElement = fakeNode.potentialAnnotatedNode;

		if (annotatedElement instanceof TypeDeclaration) {
			TypeDeclaration annotatedTypeDeclaration = (TypeDeclaration) annotatedElement;
			if (TypeDeclaration.kind(annotatedTypeDeclaration.modifiers) == TypeDeclaration.ANNOTATION_TYPE_DECL) {
				return TagBits.AnnotationForAnnotationType | TagBits.AnnotationForType;
			}
			return TagBits.AnnotationForType;
		} else if (annotatedElement instanceof FieldDeclaration) {
			if (fakeNode.isParameter) {
				return TagBits.AnnotationForParameter;
			}
			return TagBits.AnnotationForField;
		} else if (annotatedElement instanceof MethodDeclaration) {
			return TagBits.AnnotationForMethod;
		} else if (annotatedElement instanceof Argument) {
			return TagBits.AnnotationForParameter;
		} else if (annotatedElement instanceof ConstructorDeclaration) {
			return TagBits.AnnotationForConstructor;
		} else if (annotatedElement instanceof LocalDeclaration) {
			return TagBits.AnnotationForLocalVariable;
		} else if (annotatedElement instanceof ImportReference) {
			return TagBits.AnnotationForPackage;
		}
		return 0;
	}
	private TypeBinding[] computeTypes(Expression[] arguments) {
		if (arguments == null) return null;
		int argsLength = arguments.length;
		TypeBinding[] argTypes = new TypeBinding[argsLength];
		for (int a = argsLength; --a >= 0;) {
			argTypes[a] = arguments[a].resolvedType;
		}
		return argTypes;
	}

	private TypeBinding[] computeTypesIfCorrect(Expression[] arguments) {
		if (arguments == null) return null;
		int argsLength = arguments.length;
		TypeBinding[] argTypes = new TypeBinding[argsLength];
		for (int a = argsLength; --a >= 0;) {
			TypeBinding typeBinding = arguments[a].resolvedType;
			if(typeBinding == null || !typeBinding.isValidBinding()) return null;
			argTypes[a] = typeBinding;
		}
		return argTypes;
	}

	private void computeUninterestingBindings(ASTNode parent, Scope scope){
		if(parent instanceof LocalDeclaration) {
			addUninterestingBindings(((LocalDeclaration)parent).binding);
		} else if (parent instanceof FieldDeclaration) {
			addUninterestingBindings(((FieldDeclaration)parent).binding);
		}
	}

	private char[] createImportCharArray(char[] importedElement, boolean isStatic, boolean onDemand) {
		char[] result = IMPORT;
		if (isStatic) {
			result = CharOperation.concat(result, STATIC, ' ');
		}
		result = CharOperation.concat(result, importedElement, ' ');
		if (onDemand) {
			result = CharOperation.concat(result, ON_DEMAND);
		}
		return CharOperation.concat(result, IMPORT_END);
	}

	private void createMethod(MethodBinding method, char[][] parameterPackageNames, char[][] parameterTypeNames, char[][] parameterNames, Scope scope, StringBuffer completion) {
		//// Modifiers
		// flush uninteresting modifiers
		int insertedModifiers = method.modifiers & ~(ClassFileConstants.AccNative | ClassFileConstants.AccAbstract);
		if(insertedModifiers != ClassFileConstants.AccDefault){
			ASTNode.printModifiers(insertedModifiers, completion);
		}

		//// Type parameters

		TypeVariableBinding[] typeVariableBindings = method.typeVariables;
		if(typeVariableBindings != null && typeVariableBindings.length != 0) {
			completion.append('<');
			for (int i = 0; i < typeVariableBindings.length; i++) {
				if(i != 0) {
					completion.append(',');
					completion.append(' ');
				}
				createTypeVariable(typeVariableBindings[i], scope, completion);
			}
			completion.append('>');
			completion.append(' ');
		}

		//// Return type
		createType(method.returnType, scope, completion);
		completion.append(' ');

		//// Selector
		completion.append(method.selector);

		completion.append('(');

		////Parameters
		TypeBinding[] parameterTypes = method.parameters;
		int length = parameterTypes.length;
		for (int i = 0; i < length; i++) {
			if(i != 0) {
				completion.append(',');
				completion.append(' ');
			}
			createType(parameterTypes[i], scope, completion);
			completion.append(' ');
			if(parameterNames != null){
				completion.append(parameterNames[i]);
			} else {
				completion.append('%');
			}
		}

		completion.append(')');

		//// Exceptions
		ReferenceBinding[] exceptions = method.thrownExceptions;

		if (exceptions != null && exceptions.length > 0){
			completion.append(' ');
			completion.append(THROWS);
			completion.append(' ');
			for(int i = 0; i < exceptions.length ; i++){
				if(i != 0) {
					completion.append(' ');
					completion.append(',');
				}
				createType(exceptions[i], scope, completion);
			}
		}
	}

	protected InternalCompletionProposal createProposal(int kind, int completionOffset) {
		InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(kind, completionOffset - this.offset);
		proposal.nameLookup = this.nameEnvironment.nameLookup;
		proposal.completionEngine = this;
		return proposal;
	}

	private CompletionProposal createRequiredTypeProposal(Binding binding, int start, int end, int relevance) {
		InternalCompletionProposal proposal = null;
		if (binding instanceof ReferenceBinding) {
			ReferenceBinding typeBinding = (ReferenceBinding) binding;

			char[] packageName = typeBinding.qualifiedPackageName();
			char[] typeName = typeBinding.qualifiedSourceName();
			char[] fullyQualifiedName = CharOperation.concat(packageName, typeName, '.');

			proposal = createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
			proposal.nameLookup = this.nameEnvironment.nameLookup;
			proposal.completionEngine = this;
			proposal.setDeclarationSignature(packageName);
			proposal.setSignature(getRequiredTypeSignature(typeBinding));
			proposal.setPackageName(packageName);
			proposal.setTypeName(typeName);
			proposal.setCompletion(fullyQualifiedName);
			proposal.setFlags(typeBinding.modifiers);
			proposal.setReplaceRange(start - this.offset, end - this.offset);
			proposal.setTokenRange(start - this.offset, end - this.offset);
			proposal.setRelevance(relevance);
		} else if (binding instanceof PackageBinding) {
			PackageBinding packageBinding = (PackageBinding) binding;

			char[] packageName = CharOperation.concatWith(packageBinding.compoundName, '.');

			proposal = createProposal(CompletionProposal.PACKAGE_REF, this.actualCompletionPosition);
			proposal.setDeclarationSignature(packageName);
			proposal.setPackageName(packageName);
			proposal.setCompletion(packageName);
			proposal.setReplaceRange(start - this.offset, end - this.offset);
			proposal.setTokenRange(start - this.offset, end - this.offset);
			proposal.setRelevance(relevance);
		}
		return proposal;
	}

	private void createType(TypeBinding type, Scope scope, StringBuffer completion) {
		switch (type.kind()) {
			case Binding.BASE_TYPE :
				completion.append(type.sourceName());
				break;
			case Binding.WILDCARD_TYPE :
			case Binding.INTERSECTION_TYPE : // TODO (david) need to handle intersection type specifically
				WildcardBinding wildcardBinding = (WildcardBinding) type;
				completion.append('?');
				switch (wildcardBinding.boundKind) {
					case Wildcard.EXTENDS:
						completion.append(' ');
						completion.append(EXTENDS);
						completion.append(' ');
						createType(wildcardBinding.bound, scope, completion);
						if(wildcardBinding.otherBounds != null) {

							int length = wildcardBinding.otherBounds.length;
							for (int i = 0; i < length; i++) {
								completion.append(' ');
								completion.append('&');
								completion.append(' ');
								createType(wildcardBinding.otherBounds[i], scope, completion);
							}
						}
						break;
					case Wildcard.SUPER:
						completion.append(' ');
						completion.append(SUPER);
						completion.append(' ');
						createType(wildcardBinding.bound, scope, completion);
						break;
				}
				break;
			case Binding.ARRAY_TYPE :
				createType(type.leafComponentType(), scope, completion);
				int dim = type.dimensions();
				for (int i = 0; i < dim; i++) {
					completion.append('[');
					completion.append(']');
				}
				break;
			case Binding.PARAMETERIZED_TYPE :
				ParameterizedTypeBinding parameterizedType = (ParameterizedTypeBinding) type;
				if (type.isMemberType()) {
					createType(parameterizedType.enclosingType(), scope, completion);
					completion.append('.');
					completion.append(parameterizedType.sourceName);
				} else {
					completion.append(CharOperation.concatWith(parameterizedType.genericType().compoundName, '.'));
				}
				if (parameterizedType.arguments != null) {
					completion.append('<');
				    for (int i = 0, length = parameterizedType.arguments.length; i < length; i++) {
				        if (i != 0) completion.append(',');
				        createType(parameterizedType.arguments[i], scope, completion);
				    }
				    completion.append('>');
				}
				break;
			default :
				char[] packageName = type.qualifiedPackageName();
			char[] typeName = type.qualifiedSourceName();
			if(mustQualifyType(
					(ReferenceBinding)type,
					packageName,
					scope)) {
				completion.append(CharOperation.concat(packageName, typeName,'.'));
			} else {
				completion.append(type.sourceName());
			}
			break;
		}
	}

	/*
	 * Create a completion proposal for a member type.
	 */
	private void createTypeParameterProposal(TypeParameter typeParameter, int relevance) {
		char[] completionName = typeParameter.name;

		// Create standard type proposal
		if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
			InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.TYPE_REF, this.actualCompletionPosition - this.offset);
			proposal.nameLookup = this.nameEnvironment.nameLookup;
			proposal.completionEngine = this;
			proposal.setSignature(getSignature(typeParameter.binding));
			proposal.setTypeName(completionName);
			proposal.setCompletion(completionName);
			proposal.setFlags(typeParameter.modifiers);
			proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
			proposal.setRelevance(relevance);
			this.requestor.accept(proposal);
			if(DEBUG) {
				this.printDebug(proposal);
			}
		}

		// Create javadoc text proposal if necessary
		if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF)) {
			char[] javadocCompletion= inlineTagCompletion(completionName, JavadocTagConstants.TAG_LINK);
			InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.JAVADOC_TYPE_REF, this.actualCompletionPosition - this.offset);
			proposal.nameLookup = this.nameEnvironment.nameLookup;
			proposal.completionEngine = this;
			proposal.setSignature(getSignature(typeParameter.binding));
			proposal.setTypeName(javadocCompletion);
			proposal.setCompletion(javadocCompletion);
			proposal.setFlags(typeParameter.modifiers);
			proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
			proposal.setRelevance(relevance+R_INLINE_TAG);
			this.requestor.accept(proposal);
			if(DEBUG) {
				this.printDebug(proposal);
			}
		}
	}

	/*
	 * Create a completion proposal for a type.
	 */
	private void createTypeProposal(char[] packageName, char[] typeName, int modifiers, int accessibility, char[] completionName, int relevance) {

		// Create standard type proposal
		if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
			InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.TYPE_REF, this.actualCompletionPosition - this.offset);
			proposal.nameLookup = this.nameEnvironment.nameLookup;
			proposal.completionEngine = this;
			proposal.setDeclarationSignature(packageName);
			proposal.setSignature(createNonGenericTypeSignature(packageName, typeName));
			proposal.setPackageName(packageName);
			proposal.setTypeName(typeName);
			proposal.setCompletion(completionName);
			proposal.setFlags(modifiers);
			proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
			proposal.setRelevance(relevance);
			proposal.setAccessibility(accessibility);
			this.requestor.accept(proposal);
			if(DEBUG) {
				this.printDebug(proposal);
			}
		}

		// Create javadoc text proposal if necessary
		if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF)) {
			char[] javadocCompletion= inlineTagCompletion(completionName, JavadocTagConstants.TAG_LINK);
			InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.JAVADOC_TYPE_REF, this.actualCompletionPosition - this.offset);
			proposal.nameLookup = this.nameEnvironment.nameLookup;
			proposal.completionEngine = this;
			proposal.setDeclarationSignature(packageName);
			proposal.setSignature(createNonGenericTypeSignature(packageName, typeName));
			proposal.setPackageName(packageName);
			proposal.setTypeName(typeName);
			proposal.setCompletion(javadocCompletion);
			proposal.setFlags(modifiers);
			int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
			proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
			proposal.setRelevance(relevance+R_INLINE_TAG);
			proposal.setAccessibility(accessibility);
			this.requestor.accept(proposal);
			if(DEBUG) {
				this.printDebug(proposal);
			}
		}
	}

	/*
	 * Create a completion proposal for a member type.
	 */
	private void createTypeProposal(
			ReferenceBinding refBinding,
			char[] typeName,
			int accessibility,
			char[] completionName,
			int relevance,
			Binding[] missingElements,
			int[] missingElementsStarts,
			int[] missingElementsEnds,
			boolean missingElementsHaveProblems) {

		// Create standard type proposal
		if(!this.isIgnored(CompletionProposal.TYPE_REF, missingElements != null) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
			InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.TYPE_REF, this.actualCompletionPosition - this.offset);
			proposal.nameLookup = this.nameEnvironment.nameLookup;
			proposal.completionEngine = this;
			proposal.setDeclarationSignature(refBinding.qualifiedPackageName());
			proposal.setSignature(getCompletedTypeSignature(refBinding));
			proposal.setPackageName(refBinding.qualifiedPackageName());
			proposal.setTypeName(typeName);
			if (missingElements != null) {
				CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
				for (int i = 0; i < missingElements.length; i++) {
					subProposals[i] =
						createRequiredTypeProposal(
								missingElements[i],
								missingElementsStarts[i],
								missingElementsEnds[i],
								relevance);
				}
				proposal.setRequiredProposals(subProposals);
			}
			proposal.setCompletion(completionName);
			proposal.setFlags(refBinding.modifiers);
			proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
			proposal.setRelevance(relevance);
			this.requestor.accept(proposal);
			if(DEBUG) {
				this.printDebug(proposal);
			}
		}

		// Create javadoc text proposal if necessary
		if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF)) {
			char[] javadocCompletion= inlineTagCompletion(completionName, JavadocTagConstants.TAG_LINK);
			InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.JAVADOC_TYPE_REF, this.actualCompletionPosition - this.offset);
			proposal.nameLookup = this.nameEnvironment.nameLookup;
			proposal.completionEngine = this;
			proposal.setDeclarationSignature(refBinding.qualifiedPackageName());
			proposal.setSignature(getCompletedTypeSignature(refBinding));
			proposal.setPackageName(refBinding.qualifiedPackageName());
			proposal.setTypeName(typeName);
			proposal.setCompletion(javadocCompletion);
			proposal.setFlags(refBinding.modifiers);
			int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
			proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
			proposal.setRelevance(relevance+R_INLINE_TAG);
			this.requestor.accept(proposal);
			if(DEBUG) {
				this.printDebug(proposal);
			}
		}
	}
	private void createTypeVariable(TypeVariableBinding typeVariable, Scope scope, StringBuffer completion) {
		completion.append(typeVariable.sourceName);

		if (typeVariable.superclass != null && typeVariable.firstBound == typeVariable.superclass) {
		    completion.append(' ');
		    completion.append(EXTENDS);
		    completion.append(' ');
		    createType(typeVariable.superclass, scope, completion);
		}
		if (typeVariable.superInterfaces != null && typeVariable.superInterfaces != Binding.NO_SUPERINTERFACES) {
		   if (typeVariable.firstBound != typeVariable.superclass) {
			   completion.append(' ');
			   completion.append(EXTENDS);
			   completion.append(' ');
		   }
		   for (int i = 0, length = typeVariable.superInterfaces.length; i < length; i++) {
			   if (i > 0 || typeVariable.firstBound == typeVariable.superclass) {
				   completion.append(' ');
				   completion.append(EXTENDS);
				   completion.append(' ');
			   }
			   createType(typeVariable.superInterfaces[i], scope, completion);
		   }
		}
	}
	private void createVargsType(TypeBinding type, Scope scope, StringBuffer completion) {
		if (type.isArrayType()) {
			createType(type.leafComponentType(), scope, completion);
			int dim = type.dimensions() - 1;
			for (int i = 0; i < dim; i++) {
				completion.append('[');
				completion.append(']');
			}
			completion.append(VARARGS);
		} else {
			createType(type, scope, completion);
		}
	}
	private void findAnnotationAttributes(char[] token, MemberValuePair[] attributesFound, ReferenceBinding annotation) {
		MethodBinding[] methods = annotation.availableMethods();
		nextAttribute: for (int i = 0; i < methods.length; i++) {
			MethodBinding method = methods[i];

			if(!CharOperation.prefixEquals(token, method.selector, false)
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, method.selector))) continue nextAttribute;

			int length = attributesFound == null ? 0 : attributesFound.length;
			for (int j = 0; j < length; j++) {
				if(CharOperation.equals(method.selector, attributesFound[j].name, false)) continue nextAttribute;
			}

			int relevance = computeBaseRelevance();
			relevance += computeRelevanceForResolution();
			relevance += computeRelevanceForInterestingProposal(method);
			relevance += computeRelevanceForCaseMatching(token, method.selector);
			relevance += computeRelevanceForQualification(false);
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);

			this.noProposal = false;
			if(!this.requestor.isIgnored(CompletionProposal.ANNOTATION_ATTRIBUTE_REF)) {
				CompletionProposal proposal = createProposal(CompletionProposal.ANNOTATION_ATTRIBUTE_REF, this.actualCompletionPosition);
				proposal.setDeclarationSignature(getSignature(method.declaringClass));
				proposal.setSignature(getSignature(method.returnType));
				proposal.setName(method.selector);
				proposal.setCompletion(method.selector);
				proposal.setFlags(method.modifiers);
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
				proposal.setRelevance(relevance);
				this.requestor.accept(proposal);
				if(DEBUG) {
					this.printDebug(proposal);
				}
			}
		}
	}
	void findAnonymousType(
			ReferenceBinding currentType,
			TypeBinding[] argTypes,
			Scope scope,
			InvocationSite invocationSite,
			Binding[] missingElements,
			int[] missingElementsStarts,
			int[] missingElementsEnds,
			boolean missingElementsHaveProblems) {
		
		int relevance = computeBaseRelevance();
		relevance += computeRelevanceForResolution();
		relevance += computeRelevanceForInterestingProposal();
		relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
		
		if (missingElements != null) {
			relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
		}
		
		findAnonymousType(
				currentType,
				argTypes,
				scope,
				invocationSite,
				missingElements,
				missingElementsStarts,
				missingElementsEnds,
				missingElementsHaveProblems,
				true,
				false,
				relevance);
	}
	private void findAnonymousType(
		ReferenceBinding currentType,
		TypeBinding[] argTypes,
		Scope scope,
		InvocationSite invocationSite,
		Binding[] missingElements,
		int[] missingElementsStarts,
		int[] missingElementsEnds,
		boolean missingElementsHaveProblems,
		boolean exactMatch,
		boolean isQualified,
		int relevance) {

		if (currentType.isInterface()) {
			char[] completion = CharOperation.NO_CHAR;
			char[] typeCompletion = null;
			if (!exactMatch) {
				typeCompletion = 
					isQualified ?
							CharOperation.concat(currentType.qualifiedPackageName(), currentType.qualifiedSourceName(), '.') :
								currentType.sourceName();
				if (this.source != null
							&& this.source.length > this.endPosition
							&& this.source[this.endPosition] == '(') {
					completion = CharOperation.NO_CHAR;
				} else {
					completion = new char[] { '(', ')' };
				}
			}

			this.noProposal = false;
			if (!exactMatch) {
				if(!isIgnored(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)) {
					char[] packageName = currentType.isLocalType() ? null : currentType.qualifiedPackageName();
					char[] typeName = currentType.qualifiedSourceName();
					
					InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, this.actualCompletionPosition);
					proposal.setDeclarationSignature(getSignature(currentType));
					proposal.setDeclarationKey(currentType.computeUniqueKey());
					proposal.setSignature(
							createMethodSignature(
									CharOperation.NO_CHAR_CHAR,
									CharOperation.NO_CHAR_CHAR,
									CharOperation.NO_CHAR,
									CharOperation.NO_CHAR));
					//proposal.setOriginalSignature(null);
					//proposal.setUniqueKey(null);
					proposal.setDeclarationPackageName(packageName);
					proposal.setDeclarationTypeName(typeName);
					//proposal.setParameterPackageNames(null);
					//proposal.setParameterTypeNames(null);
					//proposal.setPackageName(null);
					//proposal.setTypeName(null);
					proposal.setName(currentType.sourceName());
					
					InternalCompletionProposal typeProposal = createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
					typeProposal.nameLookup = this.nameEnvironment.nameLookup;
					typeProposal.completionEngine = this;
					typeProposal.setDeclarationSignature(packageName);
					typeProposal.setSignature(getRequiredTypeSignature(currentType));
					typeProposal.setPackageName(packageName);
					typeProposal.setTypeName(typeName);
					typeProposal.setCompletion(typeCompletion);
					typeProposal.setFlags(currentType.modifiers);
					typeProposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
					typeProposal.setTokenRange(this.startPosition - this.offset, this.endPosition - this.offset);
					typeProposal.setRelevance(relevance);
					proposal.setRequiredProposals( new CompletionProposal[]{typeProposal});
								
					proposal.setCompletion(completion);
					proposal.setFlags(Flags.AccPublic);
					proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
					proposal.setRelevance(relevance);
					this.requestor.accept(proposal);
					if(DEBUG) {
						this.printDebug(proposal);
					}
				}
			}  else {
				if(!isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION, missingElements != null)) {
					InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_DECLARATION, this.actualCompletionPosition);
					proposal.setDeclarationSignature(getSignature(currentType));
					proposal.setDeclarationKey(currentType.computeUniqueKey());
					proposal.setSignature(
							createMethodSignature(
									CharOperation.NO_CHAR_CHAR,
									CharOperation.NO_CHAR_CHAR,
									CharOperation.NO_CHAR,
									CharOperation.NO_CHAR));
					//proposal.setOriginalSignature(null);
					//proposal.setUniqueKey(null);
					proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
					proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
					//proposal.setParameterPackageNames(null);
					//proposal.setParameterTypeNames(null);
					//proposal.setPackageName(null);
					//proposal.setTypeName(null);
					if (missingElements != null) {
						CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
						for (int i = 0; i < missingElements.length; i++) {
							subProposals[i] =
								createRequiredTypeProposal(
										missingElements[i],
										missingElementsStarts[i],
										missingElementsEnds[i],
										relevance);
						}
						proposal.setRequiredProposals(subProposals);
					}
					proposal.setCompletion(completion);
					proposal.setFlags(Flags.AccPublic);
					proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
					proposal.setTokenRange(this.tokenEnd - this.offset, this.tokenEnd - this.offset);
					proposal.setRelevance(relevance);
					this.requestor.accept(proposal);
					if(DEBUG) {
						this.printDebug(proposal);
					}
				}
			}
		} else {
			findConstructors(
				currentType,
				argTypes,
				scope,
				invocationSite,
				true,
				missingElements,
				missingElementsStarts,
				missingElementsEnds,
				missingElementsHaveProblems,
				exactMatch,
				isQualified,
				relevance);
		}
	}
	private void findClassField(
			char[] token,
			TypeBinding receiverType,
			Scope scope,
			Binding[] missingElements,
			int[] missingElementsStarts,
			int[] missingElementsEnds,
			boolean missingElementsHaveProblems) {

		if (token == null) return;

		if (token.length <= classField.length
			&& CharOperation.prefixEquals(token, classField, false /* ignore case */
		)) {
			int relevance = computeBaseRelevance();
			relevance += computeRelevanceForResolution();
			relevance += computeRelevanceForInterestingProposal();
			relevance += computeRelevanceForCaseMatching(token, classField);
			relevance += computeRelevanceForExpectingType(scope.getJavaLangClass());
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); //no access restriction for class field
			relevance += R_NON_INHERITED;

			if (missingElements != null) {
				relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
			}

			this.noProposal = false;
			if(!isIgnored(CompletionProposal.FIELD_REF, missingElements != null)) {
				InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
				//proposal.setDeclarationSignature(null);
				char[] signature =
					createNonGenericTypeSignature(
						CharOperation.concatWith(JAVA_LANG, '.'),
						CLASS);
				if (this.compilerOptions.sourceLevel > ClassFileConstants.JDK1_4) {
					// add type argument
					char[] typeArgument = getTypeSignature(receiverType);
					int oldLength = signature.length;
					int argumentLength = typeArgument.length;
					int newLength = oldLength + argumentLength + 2;
					System.arraycopy(signature, 0, signature = new char[newLength], 0, oldLength - 1);
					signature[oldLength - 1] = '<';
					System.arraycopy(typeArgument, 0, signature, oldLength , argumentLength);
					signature[newLength - 2] = '>';
					signature[newLength - 1] = ';';
				}
				proposal.setSignature(signature);
				//proposal.setDeclarationPackageName(null);
				//proposal.setDeclarationTypeName(null);
				proposal.setPackageName(CharOperation.concatWith(JAVA_LANG, '.'));
				proposal.setTypeName(CLASS);
				proposal.setName(classField);
				if (missingElements != null) {
					CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
					for (int i = 0; i < missingElements.length; i++) {
						subProposals[i] =
							createRequiredTypeProposal(
									missingElements[i],
									missingElementsStarts[i],
									missingElementsEnds[i],
									relevance);
					}
					proposal.setRequiredProposals(subProposals);
				}
				proposal.setCompletion(classField);
				proposal.setFlags(Flags.AccStatic | Flags.AccPublic);
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
				proposal.setRelevance(relevance);
				this.requestor.accept(proposal);
				if(DEBUG) {
					this.printDebug(proposal);
				}
			}
		}
	}
	
	void findConstructors(
		ReferenceBinding currentType,
		TypeBinding[] argTypes,
		Scope scope,
		InvocationSite invocationSite,
		boolean forAnonymousType,
		Binding[] missingElements,
		int[] missingElementsStarts,
		int[] missingElementsEnds,
		boolean missingElementsHaveProblems) {
		
		int relevance = computeBaseRelevance();
		relevance += computeRelevanceForResolution();
		relevance += computeRelevanceForInterestingProposal();
		relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
		
		if (missingElements != null) {
			relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
		}
		
		findConstructors(
				currentType,
				argTypes,
				scope,
				invocationSite,
				forAnonymousType,
				missingElements,
				missingElementsStarts,
				missingElementsEnds,
				missingElementsHaveProblems,
				true,
				false,
				relevance);
	}
	
	
	private void findConstructorsFromMissingType(
			TypeReference typeRef,
			final TypeBinding[] argTypes,
			final Scope scope,
			final InvocationSite invocationSite) {
		MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this);
		MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor =
			new MissingTypesGuesser.GuessedTypeRequestor() {
				public void accept(
						TypeBinding guessedType,
						Binding[] missingElements,
						int[] missingElementsStarts,
						int[] missingElementsEnds,
						boolean hasProblems) {
					if (guessedType instanceof ReferenceBinding) {
						ReferenceBinding ref = (ReferenceBinding) guessedType;
						if (!isIgnored(CompletionProposal.METHOD_REF, missingElements != null)
								&& ref.isClass()
								&& !ref.isAbstract()) {
								findConstructors(
									ref,
									argTypes,
									scope,
									invocationSite,
									false,
									missingElements,
									missingElementsStarts,
									missingElementsEnds,
									hasProblems);
						}
								
						checkCancel();
			
						if (!isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION, missingElements != null)
								&& !ref.isFinal()
								&& !ref.isEnum()){
							findAnonymousType(
								ref,
								argTypes,
								scope,
								invocationSite,
								missingElements,
								missingElementsStarts,
								missingElementsEnds,
								hasProblems);
						}
					}
				}
			};
		missingTypesConverter.guess(typeRef, scope, substitutionRequestor);
	}
		
	private void findConstructors(
		ReferenceBinding currentType,
		TypeBinding[] argTypes,
		Scope scope,
		InvocationSite invocationSite,
		boolean forAnonymousType,
		Binding[] missingElements,
		int[] missingElementsStarts,
		int[] missingElementsEnds,
		boolean missingElementsHaveProblems,
		boolean exactMatch,
		boolean isQualified,
		int relevance) {

		// No visibility checks can be performed without the scope & invocationSite
		MethodBinding[] methods = currentType.availableMethods();
		if(methods != null) {
			int minArgLength = argTypes == null ? 0 : argTypes.length;
			next : for (int f = methods.length; --f >= 0;) {
				MethodBinding constructor = methods[f];
				if (constructor.isConstructor()) {

					if (constructor.isSynthetic()) continue next;

					if (this.options.checkDeprecation &&
							constructor.isViewedAsDeprecated() &&
							!scope.isDefinedInSameUnit(constructor.declaringClass))
						continue next;

					if (this.options.checkVisibility
						&& !constructor.canBeSeenBy(invocationSite, scope)) {
						if(!forAnonymousType || !constructor.isProtected())
							continue next;
					}

					TypeBinding[] parameters = constructor.parameters;
					int paramLength = parameters.length;
					if (minArgLength > paramLength)
						continue next;
					for (int a = minArgLength; --a >= 0;)
						if (argTypes[a] != null) { // can be null if it could not be resolved properly
							if (!argTypes[a].isCompatibleWith(constructor.parameters[a]))
								continue next;
						}

					char[][] parameterPackageNames = new char[paramLength][];
					char[][] parameterTypeNames = new char[paramLength][];
					for (int i = 0; i < paramLength; i++) {
						TypeBinding type = parameters[i];
						parameterPackageNames[i] = type.qualifiedPackageName();
						parameterTypeNames[i] = type.qualifiedSourceName();
					}
					char[][] parameterNames = findMethodParameterNames(constructor,parameterTypeNames);

					char[] completion = CharOperation.NO_CHAR;
					
					if(forAnonymousType){
						char[] typeCompletion = null;
						if (!exactMatch) {
							typeCompletion = 
								isQualified ?
										CharOperation.concat(currentType.qualifiedPackageName(), currentType.qualifiedSourceName(), '.') :
											currentType.sourceName();
							if (this.source != null
										&& this.source.length > this.endPosition
										&& this.source[this.endPosition] == '(') {
								completion = CharOperation.NO_CHAR;
							} else {
								completion = new char[] { '(', ')' };
							}
						}
						
						this.noProposal = false;
						if (!exactMatch) {
							if(!isIgnored(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)) {
								char[] packageName = currentType.isLocalType() ? null : currentType.qualifiedPackageName();
								char[] typeName = currentType.qualifiedSourceName();
								
								InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, this.actualCompletionPosition);
								proposal.setDeclarationSignature(getSignature(currentType));
								proposal.setDeclarationKey(currentType.computeUniqueKey());
								proposal.setSignature(getSignature(constructor));
								MethodBinding original = constructor.original();
								if(original != constructor) {
									proposal.setOriginalSignature(getSignature(original));
								}
								proposal.setKey(constructor.computeUniqueKey());
								proposal.setDeclarationPackageName(packageName);
								proposal.setDeclarationTypeName(typeName);
								proposal.setParameterPackageNames(parameterPackageNames);
								proposal.setParameterTypeNames(parameterTypeNames);
								//proposal.setPackageName(null);
								//proposal.setTypeName(null);
								proposal.setName(currentType.sourceName());
								
								InternalCompletionProposal typeProposal = createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
								typeProposal.nameLookup = this.nameEnvironment.nameLookup;
								typeProposal.completionEngine = this;
								typeProposal.setDeclarationSignature(packageName);
								typeProposal.setSignature(getRequiredTypeSignature(currentType));
								typeProposal.setPackageName(packageName);
								typeProposal.setTypeName(typeName);
								typeProposal.setCompletion(typeCompletion);
								typeProposal.setFlags(currentType.modifiers);
								typeProposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
								typeProposal.setTokenRange(this.startPosition - this.offset, this.endPosition - this.offset);
								typeProposal.setRelevance(relevance);
								proposal.setRequiredProposals( new CompletionProposal[]{typeProposal});
								
								proposal.setCompletion(completion);
								proposal.setFlags(constructor.modifiers);
								proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
								proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
								proposal.setRelevance(relevance);
								if(parameterNames != null) proposal.setParameterNames(parameterNames);
								this.requestor.accept(proposal);
								if(DEBUG) {
									this.printDebug(proposal);
								}
							}
						} else {
							if(!isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION, missingElements != null)) {
								InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_DECLARATION, this.actualCompletionPosition);
								proposal.setDeclarationSignature(getSignature(currentType));
								proposal.setDeclarationKey(currentType.computeUniqueKey());
								proposal.setSignature(getSignature(constructor));
								MethodBinding original = constructor.original();
								if(original != constructor) {
									proposal.setOriginalSignature(getSignature(original));
								}
								proposal.setKey(constructor.computeUniqueKey());
								proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
								proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
								proposal.setParameterPackageNames(parameterPackageNames);
								proposal.setParameterTypeNames(parameterTypeNames);
								//proposal.setPackageName(null);
								//proposal.setTypeName(null);
								if (missingElements != null) {
									CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
									for (int i = 0; i < missingElements.length; i++) {
										subProposals[i] =
											createRequiredTypeProposal(
													missingElements[i],
													missingElementsStarts[i],
													missingElementsEnds[i],
													relevance);
									}
									proposal.setRequiredProposals(subProposals);
								}
								proposal.setCompletion(completion);
								proposal.setFlags(constructor.modifiers);
								proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
								proposal.setTokenRange(this.tokenEnd - this.offset, this.tokenEnd - this.offset);
								proposal.setRelevance(relevance);
								if(parameterNames != null) proposal.setParameterNames(parameterNames);
								this.requestor.accept(proposal);
								if(DEBUG) {
									this.printDebug(proposal);
								}
							}
						}
					} else {
						char[] typeCompletion = null;
						// Special case for completion in javadoc
						if (this.assistNodeInJavadoc > 0) {
							Expression receiver = null;
							char[] selector = null;
							if (invocationSite instanceof CompletionOnJavadocAllocationExpression) {
								CompletionOnJavadocAllocationExpression alloc = (CompletionOnJavadocAllocationExpression) invocationSite;
								receiver = alloc.type;
							} else if (invocationSite instanceof CompletionOnJavadocFieldReference) {
								CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) invocationSite;
								receiver = fieldRef.receiver;
							}
							if (receiver != null) {
								StringBuffer javadocCompletion = new StringBuffer();
								if (receiver.isThis()) {
									selector = (((JavadocImplicitTypeReference)receiver).token);
									if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
										javadocCompletion.append('#');
									}
								} else if (receiver instanceof JavadocSingleTypeReference) {
									JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) receiver;
									selector = typeRef.token;
									if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
										javadocCompletion.append(typeRef.token);
										javadocCompletion.append('#');
									}
								} else if (receiver instanceof JavadocQualifiedTypeReference) {
									JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) receiver;
									selector = typeRef.tokens[typeRef.tokens.length-1];
									if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
										javadocCompletion.append(CharOperation.concatWith(typeRef.tokens, '.'));
										javadocCompletion.append('#');
									}
								}
								// Append parameters types
								javadocCompletion.append(selector);
								javadocCompletion.append('(');
								if (constructor.parameters != null) {
									boolean isVarargs = constructor.isVarargs();
									for (int p=0, ln=constructor.parameters.length; p<ln; p++) {
										if (p>0) javadocCompletion.append(", "); //$NON-NLS-1$
										TypeBinding argTypeBinding = constructor.parameters[p];
										if (isVarargs && p == ln - 1)  {
											createVargsType(argTypeBinding.erasure(), scope, javadocCompletion);
										} else {
											createType(argTypeBinding.erasure(), scope, javadocCompletion);
										}
									}
								}
								javadocCompletion.append(')');
								completion = javadocCompletion.toString().toCharArray();
							}
						} else {
							if (!exactMatch) {
								typeCompletion = 
									isQualified ?
											CharOperation.concat(currentType.qualifiedPackageName(), currentType.qualifiedSourceName(), '.') :
												currentType.sourceName();
								
								if (this.source != null
											&& this.source.length > this.endPosition
											&& this.source[this.endPosition] == '(') {
									completion = CharOperation.NO_CHAR;
								} else {
									completion = new char[] { '(', ')' };
								}
							}
						}

						// Create standard proposal
						this.noProposal = false;
						if (!exactMatch) {
							if(!isIgnored(CompletionProposal.CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)) {
								char[] packageName = currentType.isLocalType() ? null : currentType.qualifiedPackageName();
								char[] typeName = currentType.qualifiedSourceName();
								
								InternalCompletionProposal proposal =  createProposal(CompletionProposal.CONSTRUCTOR_INVOCATION, this.actualCompletionPosition);
								proposal.setDeclarationSignature(getSignature(currentType));
								proposal.setSignature(getSignature(constructor));
								MethodBinding original = constructor.original();
								if(original != constructor) {
									proposal.setOriginalSignature(getSignature(original));
								}
								proposal.setDeclarationPackageName(packageName);
								proposal.setDeclarationTypeName(typeName);
								proposal.setParameterPackageNames(parameterPackageNames);
								proposal.setParameterTypeNames(parameterTypeNames);
								//proposal.setPackageName(null);
								//proposal.setTypeName(null);
								proposal.setName(currentType.sourceName());
					
								InternalCompletionProposal typeProposal = createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
								typeProposal.nameLookup = this.nameEnvironment.nameLookup;
								typeProposal.completionEngine = this;
								typeProposal.setDeclarationSignature(packageName);
								typeProposal.setSignature(getRequiredTypeSignature(currentType));
								typeProposal.setPackageName(packageName);
								typeProposal.setTypeName(typeName);
								typeProposal.setCompletion(typeCompletion);
								typeProposal.setFlags(currentType.modifiers);
								typeProposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
								typeProposal.setTokenRange(this.startPosition - this.offset, this.endPosition - this.offset);
								typeProposal.setRelevance(relevance);
								proposal.setRequiredProposals( new CompletionProposal[]{typeProposal});
								
								proposal.setIsContructor(true);
								proposal.setCompletion(completion);
								proposal.setFlags(constructor.modifiers);
								proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
								proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
								proposal.setRelevance(relevance);
								if(parameterNames != null) proposal.setParameterNames(parameterNames);
								this.requestor.accept(proposal);
								if(DEBUG) {
									this.printDebug(proposal);
								}
							}
						} else {
							if(!isIgnored(CompletionProposal.METHOD_REF, missingElements != null) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
								InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
								proposal.setDeclarationSignature(getSignature(currentType));
								proposal.setSignature(getSignature(constructor));
								MethodBinding original = constructor.original();
								if(original != constructor) {
									proposal.setOriginalSignature(getSignature(original));
								}
								proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
								proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
								proposal.setParameterPackageNames(parameterPackageNames);
								proposal.setParameterTypeNames(parameterTypeNames);
								//proposal.setPackageName(null);
								//proposal.setTypeName(null);
								proposal.setName(currentType.sourceName());
								if (missingElements != null) {
									CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
									for (int i = 0; i < missingElements.length; i++) {
										subProposals[i] =
											createRequiredTypeProposal(
													missingElements[i],
													missingElementsStarts[i],
													missingElementsEnds[i],
													relevance);
									}
									proposal.setRequiredProposals(subProposals);
								}
								proposal.setIsContructor(true);
								proposal.setCompletion(completion);
								proposal.setFlags(constructor.modifiers);
								int start = (this.assistNodeInJavadoc > 0) ? this.startPosition : this.endPosition;
								proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
								proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
								proposal.setRelevance(relevance);
								if(parameterNames != null) proposal.setParameterNames(parameterNames);
								this.requestor.accept(proposal);
								if(DEBUG) {
									this.printDebug(proposal);
								}
							}
							if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_METHOD_REF)) {
								char[] javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_LINK);
								InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_METHOD_REF, this.actualCompletionPosition);
								proposal.setDeclarationSignature(getSignature(currentType));
								proposal.setSignature(getSignature(constructor));
								MethodBinding original = constructor.original();
								if(original != constructor) {
									proposal.setOriginalSignature(getSignature(original));
								}
								proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
								proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
								proposal.setParameterPackageNames(parameterPackageNames);
								proposal.setParameterTypeNames(parameterTypeNames);
								//proposal.setPackageName(null);
								//proposal.setTypeName(null);
								proposal.setName(currentType.sourceName());
								proposal.setIsContructor(true);
								proposal.setCompletion(javadocCompletion);
								proposal.setFlags(constructor.modifiers);
								int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
								proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
								proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
								proposal.setRelevance(relevance+R_INLINE_TAG);
								if(parameterNames != null) proposal.setParameterNames(parameterNames);
								this.requestor.accept(proposal);
								if(DEBUG) {
									this.printDebug(proposal);
								}
							}
						}
					}
				}
			}
		}
	}
	
	private char[] getResolvedSignature(char[][] parameterTypes, char[] fullyQualifiedTypeName, int parameterCount, Scope scope) {
		char[][] cn = CharOperation.splitOn('.', fullyQualifiedTypeName);

		TypeReference ref;
		if (cn.length == 1) {
			ref = new SingleTypeReference(cn[0], 0);
		} else {
			ref = new QualifiedTypeReference(cn,new long[cn.length]);
		}
		
		TypeBinding guessedType = null;
		INameEnvironment oldNameEnvironment = this.lookupEnvironment.nameEnvironment;
		this.lookupEnvironment.nameEnvironment = getNoCacheNameEnvironment();
		try {
			switch (scope.kind) {
				case Scope.METHOD_SCOPE :
				case Scope.BLOCK_SCOPE :
					guessedType = ref.resolveType((BlockScope)scope);
					break;
				case Scope.CLASS_SCOPE :
					guessedType = ref.resolveType((ClassScope)scope);
					break;
			}
		

			if (guessedType != null && guessedType.isValidBinding()) {
				// the erasure must be used because guessedType can be a RawTypeBinding (https://bugs.eclipse.org/bugs/show_bug.cgi?id=276890)
				guessedType = guessedType.erasure();
				
				if (guessedType instanceof SourceTypeBinding) {
					SourceTypeBinding refBinding = (SourceTypeBinding) guessedType;
					
					if (refBinding.scope == null || refBinding.scope.referenceContext == null) return null;
					
					TypeDeclaration typeDeclaration = refBinding.scope.referenceContext;
					AbstractMethodDeclaration[] methods = typeDeclaration.methods;
					
					next : for (int i = 0; i < methods.length; i++) {
						AbstractMethodDeclaration method = methods[i];
						
						if (!method.isConstructor()) continue next;
						
						Argument[] arguments = method.arguments;
						int argumentsLength = arguments == null ? 0 : arguments.length;
						
						if (parameterCount != argumentsLength) continue next;
						
						for (int j = 0; j < argumentsLength; j++) {
							char[] argumentTypeName = getTypeName(arguments[j].type);
	
							if (!CharOperation.equals(argumentTypeName, parameterTypes[j])) {
								continue next;
							}
						}
						
						refBinding.resolveTypesFor(method.binding); // force resolution
						if (method.binding == null) continue next;
						return getSignature(method.binding);
					}
				}
			}
		} finally {
			this.lookupEnvironment.nameEnvironment = oldNameEnvironment;
		}
		
		return null;
	}
	
	private void findConstructorsOrAnonymousTypes(
			ReferenceBinding currentType,
			Scope scope,
			InvocationSite invocationSite,
			boolean isQualified,
			int relevance) {
		
		if (!isIgnored(CompletionProposal.CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)
				&& currentType.isClass()
				&& !currentType.isAbstract()) {
				findConstructors(
					currentType,
					null,
					scope,
					invocationSite,
					false,
					null,
					null,
					null,
					false,
					false,
					isQualified,
					relevance);
		}
		
		// This code is disabled because there is too much proposals when constructors and anonymous are proposed
		if (!isIgnored(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)
				&& !currentType.isFinal()
				&& (currentType.isInterface() || (currentType.isClass() && currentType.isAbstract()))){
			findAnonymousType(
				currentType,
				null,
				scope,
				invocationSite,
				null,
				null,
				null,
				false,
				false,
				isQualified,
				relevance);
		}
	}
	private char[][] findEnclosingTypeNames(Scope scope){
		char[][] excludedNames = new char[10][];
		int excludedNameCount = 0;

		Scope currentScope = scope;
		while(currentScope != null) {
			switch (currentScope.kind) {
				case Scope.CLASS_SCOPE :
					ClassScope classScope = (ClassScope) currentScope;

					TypeDeclaration typeDeclaration = classScope.referenceContext;

					if(excludedNameCount == excludedNames.length) {
						System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount * 2][], 0, excludedNameCount);
					}
					excludedNames[excludedNameCount++] = typeDeclaration.name;

					TypeParameter[] classTypeParameters = typeDeclaration.typeParameters;
					if(classTypeParameters != null) {
						for (int i = 0; i < classTypeParameters.length; i++) {
							TypeParameter typeParameter = classTypeParameters[i];
							if(excludedNameCount == excludedNames.length) {
								System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount * 2][], 0, excludedNameCount);
							}
							excludedNames[excludedNameCount++] = typeParameter.name;
						}
					}
					break;
				case Scope.METHOD_SCOPE :
					MethodScope methodScope = (MethodScope) currentScope;
					if(methodScope.referenceContext instanceof AbstractMethodDeclaration) {
						TypeParameter[] methodTypeParameters = ((AbstractMethodDeclaration)methodScope.referenceContext).typeParameters();
						if(methodTypeParameters != null) {
							for (int i = 0; i < methodTypeParameters.length; i++) {
								TypeParameter typeParameter = methodTypeParameters[i];
								if(excludedNameCount == excludedNames.length) {
									System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount * 2][], 0, excludedNameCount);
								}
								excludedNames[excludedNameCount++] = typeParameter.name;
							}
						}
					}
					break;
			}

			currentScope = currentScope.parent;
		}

		if(excludedNameCount == 0) {
			return CharOperation.NO_CHAR_CHAR;
		}
		System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount][], 0, excludedNameCount);
		return excludedNames;
	}
	private void findEnumConstants(
			char[] enumConstantName,
			ReferenceBinding enumType,
			Scope invocationScope,
			ObjectVector fieldsFound,
			char[][] alreadyUsedConstants,
			int alreadyUsedConstantCount,
			boolean needQualification) {

		FieldBinding[] fields = enumType.fields();

		int enumConstantLength = enumConstantName.length;
		next : for (int f = fields.length; --f >= 0;) {
			FieldBinding field = fields[f];

			if (field.isSynthetic()) continue next;

			if ((field.modifiers & Flags.AccEnum) == 0) continue next;

			if (enumConstantLength > field.name.length) continue next;

			if (!CharOperation.prefixEquals(enumConstantName, field.name, false /* ignore case */)
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(enumConstantName, field.name)))	continue next;

			char[] fieldName = field.name;

			for (int i = 0; i < alreadyUsedConstantCount; i++) {
				if(CharOperation.equals(alreadyUsedConstants[i], fieldName)) continue next;
			}

			int relevance = computeBaseRelevance();
			relevance += computeRelevanceForResolution();
			relevance += computeRelevanceForInterestingProposal(field);
			relevance += computeRelevanceForCaseMatching(enumConstantName, field.name);
			relevance += computeRelevanceForExpectingType(field.type);
			relevance += computeRelevanceForEnumConstant(field.type);
			relevance += computeRelevanceForQualification(needQualification);
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);

			this.noProposal = false;
			if (!needQualification) {
				char[] completion = fieldName;

				if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
					InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
					proposal.setDeclarationSignature(getSignature(field.declaringClass));
					proposal.setSignature(getSignature(field.type));
					proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
					proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
					proposal.setPackageName(field.type.qualifiedPackageName());
					proposal.setTypeName(field.type.qualifiedSourceName());
					proposal.setName(field.name);
					proposal.setCompletion(completion);
					proposal.setFlags(field.modifiers);
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
					proposal.setRelevance(relevance);
					this.requestor.accept(proposal);
					if(DEBUG) {
						this.printDebug(proposal);
					}
				}

			} else {
				TypeBinding visibleType = invocationScope.getType(field.type.sourceName());
				boolean needImport = visibleType == null || !visibleType.isValidBinding();

				char[] completion = CharOperation.concat(field.type.sourceName(), field.name, '.');

				if (!needImport) {
					if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
						InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
						proposal.setDeclarationSignature(getSignature(field.declaringClass));
						proposal.setSignature(getSignature(field.type));
						proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
						proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
						proposal.setPackageName(field.type.qualifiedPackageName());
						proposal.setTypeName(field.type.qualifiedSourceName());
						proposal.setName(field.name);
						proposal.setCompletion(completion);
						proposal.setFlags(field.modifiers);
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
						proposal.setRelevance(relevance);
						this.requestor.accept(proposal);
						if(DEBUG) {
							this.printDebug(proposal);
						}
					}
				} else {
					if (!this.isIgnored(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_IMPORT)) {
						CompilationUnitDeclaration cu = this.unitScope.referenceContext;
						int importStart = cu.types[0].declarationSourceStart;
						int importEnd = importStart;

						ReferenceBinding fieldType = (ReferenceBinding)field.type;

						InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
						proposal.setDeclarationSignature(getSignature(field.declaringClass));
						proposal.setSignature(getSignature(field.type));
						proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
						proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
						proposal.setPackageName(field.type.qualifiedPackageName());
						proposal.setTypeName(field.type.qualifiedSourceName());
						proposal.setName(field.name);
						proposal.setCompletion(completion);
						proposal.setFlags(field.modifiers);
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
						proposal.setRelevance(relevance);

						char[] typeImportCompletion = createImportCharArray(CharOperation.concatWith(fieldType.compoundName, '.'), false, false);

						InternalCompletionProposal typeImportProposal = createProposal(CompletionProposal.TYPE_IMPORT, this.actualCompletionPosition);
						typeImportProposal.nameLookup = this.nameEnvironment.nameLookup;
						typeImportProposal.completionEngine = this;
						char[] packageName = fieldType.qualifiedPackageName();
						typeImportProposal.setDeclarationSignature(packageName);
						typeImportProposal.setSignature(getSignature(fieldType));
						typeImportProposal.setPackageName(packageName);
						typeImportProposal.setTypeName(fieldType.qualifiedSourceName());
						typeImportProposal.setCompletion(typeImportCompletion);
						typeImportProposal.setFlags(fieldType.modifiers);
						typeImportProposal.setAdditionalFlags(CompletionFlags.Default);
						typeImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
						typeImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset);
						typeImportProposal.setRelevance(relevance);

						proposal.setRequiredProposals(new CompletionProposal[]{typeImportProposal});

						this.requestor.accept(proposal);
						if(DEBUG) {
							this.printDebug(proposal);
						}
					}
				}
			}
		}
	}
	private void findEnumConstantsFromExpectedTypes(
			char[] token,
			Scope invocationScope,
			ObjectVector fieldsFound) {
		int length = this.expectedTypesPtr + 1;
		for (int i = 0; i < length; i++) {
			if (this.expectedTypes[i].isEnum()) {
				findEnumConstants(
						token,
						(ReferenceBinding)this.expectedTypes[i],
						invocationScope,
						fieldsFound,
						CharOperation.NO_CHAR_CHAR,
						0,
						true);
			}
		}

	}
	private void findEnumConstantsFromSwithStatement(char[] enumConstantName, SwitchStatement switchStatement) {
		TypeBinding expressionType = switchStatement.expression.resolvedType;
		if(expressionType != null && expressionType.isEnum()) {
			ReferenceBinding enumType = (ReferenceBinding) expressionType;

			CaseStatement[] cases = switchStatement.cases;

			char[][] alreadyUsedConstants = new char[switchStatement.caseCount][];
			int alreadyUsedConstantCount = 0;
			for (int i = 0; i < switchStatement.caseCount; i++) {
				Expression caseExpression = cases[i].constantExpression;
				if((caseExpression instanceof SingleNameReference)
						&& (caseExpression.resolvedType != null && caseExpression.resolvedType.isEnum())) {
					alreadyUsedConstants[alreadyUsedConstantCount++] = ((SingleNameReference)cases[i].constantExpression).token;
				}
			}

			findEnumConstants(
					enumConstantName,
					enumType,
					null /* doesn't need invocation scope */,
					new ObjectVector(),
					alreadyUsedConstants,
					alreadyUsedConstantCount,
					false);
		}
	}
	private void findExceptionFromTryStatement(
			char[] typeName,
			ReferenceBinding exceptionType,
			ReferenceBinding receiverType,
			SourceTypeBinding invocationType,
			BlockScope scope,
			ObjectVector typesFound,
			boolean searchSuperClasses) {

		if (searchSuperClasses) {
			ReferenceBinding javaLangThrowable = scope.getJavaLangThrowable();
			if (exceptionType != javaLangThrowable) {
				ReferenceBinding superClass = exceptionType.superclass();
				while(superClass != null && superClass != javaLangThrowable) {
					findExceptionFromTryStatement(typeName, superClass, receiverType, invocationType, scope, typesFound, false);
					superClass = superClass.superclass();
				}
			}
		}

		if (typeName.length > exceptionType.sourceName.length)
			return;

		if (!CharOperation.prefixEquals(typeName, exceptionType.sourceName, false/* ignore case */)
				&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, exceptionType.sourceName)))
			return;

		if (this.options.checkDeprecation &&
				exceptionType.isViewedAsDeprecated() &&
				!scope.isDefinedInSameUnit(exceptionType))
			return;

		if (this.options.checkVisibility) {
			if (invocationType != null) {
				if (receiverType != null) {
					if (!exceptionType.canBeSeenBy(receiverType, invocationType)) return;
				} else {
					if (!exceptionType.canBeSeenBy(exceptionType, invocationType)) return;
				}
			} else if(!exceptionType.canBeSeenBy(this.unitScope.fPackage)) {
				return;
			}
		}

		for (int j = typesFound.size; --j >= 0;) {
			ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(j);

			if (exceptionType == otherType)
				return;

			if (CharOperation.equals(exceptionType.sourceName, otherType.sourceName, true)) {

				if (exceptionType.enclosingType().isSuperclassOf(otherType.enclosingType()))
					return;

				if (otherType.enclosingType().isInterface())
					if (exceptionType.enclosingType()
						.implementsInterface(otherType.enclosingType(), true))
						return;

				if (exceptionType.enclosingType().isInterface())
					if (otherType.enclosingType()
						.implementsInterface(exceptionType.enclosingType(), true))
						return;
			}
		}

		typesFound.add(exceptionType);

		char[] completionName = exceptionType.sourceName();

		boolean isQualified = false;

		if(!this.insideQualifiedReference) {
			isQualified = true;

			char[] memberPackageName = exceptionType.qualifiedPackageName();
			char[] memberTypeName = exceptionType.sourceName();
			char[] memberEnclosingTypeNames = null;

			ReferenceBinding enclosingType = exceptionType.enclosingType();
			if (enclosingType != null) {
				memberEnclosingTypeNames = exceptionType.enclosingType().qualifiedSourceName();
			}

			Scope currentScope = scope;
			done : while (currentScope != null) { // done when a COMPILATION_UNIT_SCOPE is found

				switch (currentScope.kind) {

					case Scope.METHOD_SCOPE :
					case Scope.BLOCK_SCOPE :
						BlockScope blockScope = (BlockScope) currentScope;

						for (int j = 0, length = blockScope.subscopeCount; j < length; j++) {

							if (blockScope.subscopes[j] instanceof ClassScope) {
								SourceTypeBinding localType =
									((ClassScope) blockScope.subscopes[j]).referenceContext.binding;

								if (localType == exceptionType) {
									isQualified = false;
									break done;
								}
							}
						}
						break;

					case Scope.CLASS_SCOPE :
						SourceTypeBinding type = ((ClassScope)currentScope).referenceContext.binding;
						ReferenceBinding[] memberTypes = type.memberTypes();
						if (memberTypes != null) {
							for (int j = 0; j < memberTypes.length; j++) {
								if (memberTypes[j] == exceptionType) {
									isQualified = false;
									break done;
								}
							}
						}


						break;

					case Scope.COMPILATION_UNIT_SCOPE :
						SourceTypeBinding[] types = ((CompilationUnitScope)currentScope).topLevelTypes;
						if (types != null) {
							for (int j = 0; j < types.length; j++) {
								if (types[j] == exceptionType) {
									isQualified = false;
									break done;
								}
							}
						}
						break done;
				}
				currentScope = currentScope.parent;
			}

			if (isQualified && mustQualifyType(memberPackageName, memberTypeName, memberEnclosingTypeNames, exceptionType.modifiers)) {
				if (memberPackageName == null || memberPackageName.length == 0)
					if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
						return; // ignore types from the default package from outside it
			} else {
				isQualified = false;
			}

			if (isQualified) {
				completionName =
					CharOperation.concat(
							memberPackageName,
							CharOperation.concat(
									memberEnclosingTypeNames,
									memberTypeName,
									'.'),
							'.');
			}
		}

		int relevance = computeBaseRelevance();
		relevance += computeRelevanceForResolution();
		relevance += computeRelevanceForInterestingProposal();
		relevance += computeRelevanceForCaseMatching(typeName, exceptionType.sourceName);
		relevance += computeRelevanceForExpectingType(exceptionType);
		relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
		if(!this.insideQualifiedReference) {
			relevance += computeRelevanceForQualification(isQualified);
		}
		relevance += computeRelevanceForClass();
		relevance += computeRelevanceForException();

		this.noProposal = false;
		if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
			createTypeProposal(
					exceptionType,
					exceptionType.qualifiedSourceName(),
					IAccessRule.K_ACCESSIBLE,
					completionName,
					relevance,
					null,
					null,
					null,
					false);
		}
	}
	private void findExceptionFromTryStatement(
			char[] typeName,
			ReferenceBinding receiverType,
			SourceTypeBinding invocationType,
			BlockScope scope,
			ObjectVector typesFound) {

		for (int i = 0; i <= this.expectedTypesPtr; i++) {
			ReferenceBinding exceptionType = (ReferenceBinding)this.expectedTypes[i];

			findExceptionFromTryStatement(typeName, exceptionType, receiverType, invocationType, scope, typesFound, true);
		}
	}
	private void findExplicitConstructors(
		char[] name,
		ReferenceBinding currentType,
		MethodScope scope,
		InvocationSite invocationSite) {

		ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration)scope.referenceContext;
		MethodBinding enclosingConstructor = constructorDeclaration.binding;

		// No visibility checks can be performed without the scope & invocationSite
		MethodBinding[] methods = currentType.availableMethods();
		if(methods != null) {
			next : for (int f = methods.length; --f >= 0;) {
				MethodBinding constructor = methods[f];
				if (constructor != enclosingConstructor && constructor.isConstructor()) {

					if (constructor.isSynthetic()) continue next;

					if (this.options.checkDeprecation &&
							constructor.isViewedAsDeprecated() &&
							!scope.isDefinedInSameUnit(constructor.declaringClass))
						continue next;

					if (this.options.checkVisibility
						&& !constructor.canBeSeenBy(invocationSite, scope))	continue next;

					TypeBinding[] parameters = constructor.parameters;
					int paramLength = parameters.length;

					char[][] parameterPackageNames = new char[paramLength][];
					char[][] parameterTypeNames = new char[paramLength][];
					for (int i = 0; i < paramLength; i++) {
						TypeBinding type = parameters[i];
						parameterPackageNames[i] = type.qualifiedPackageName();
						parameterTypeNames[i] = type.qualifiedSourceName();
					}
					char[][] parameterNames = findMethodParameterNames(constructor,parameterTypeNames);

					char[] completion = CharOperation.NO_CHAR;
					if (this.source != null
						&& this.source.length > this.endPosition
						&& this.source[this.endPosition] == '(')
						completion = name;
					else
						completion = CharOperation.concat(name, new char[] { '(', ')' });

					int relevance = computeBaseRelevance();
					relevance += computeRelevanceForResolution();
					relevance += computeRelevanceForInterestingProposal();
					relevance += computeRelevanceForCaseMatching(this.completionToken, name);
					relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);

					this.noProposal = false;
					if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
						proposal.setDeclarationSignature(getSignature(currentType));
						proposal.setSignature(getSignature(constructor));
						MethodBinding original = constructor.original();
						if(original != constructor) {
							proposal.setOriginalSignature(getSignature(original));
						}
						proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
						proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
						proposal.setParameterPackageNames(parameterPackageNames);
						proposal.setParameterTypeNames(parameterTypeNames);
						//proposal.setPackageName(null);
						//proposal.setTypeName(null);
						proposal.setName(name);
						proposal.setIsContructor(true);
						proposal.setCompletion(completion);
						proposal.setFlags(constructor.modifiers);
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
						proposal.setRelevance(relevance);
						if(parameterNames != null) proposal.setParameterNames(parameterNames);
						this.requestor.accept(proposal);
						if(DEBUG) {
							this.printDebug(proposal);
						}
					}
				}
			}
		}
	}
	// Helper method for findFields(char[], ReferenceBinding, Scope, ObjectVector, boolean)
	private void findFields(
		char[] fieldName,
		FieldBinding[] fields,
		Scope scope,
		ObjectVector fieldsFound,
		ObjectVector localsFound,
		boolean onlyStaticFields,
		ReferenceBinding receiverType,
		InvocationSite invocationSite,
		Scope invocationScope,
		boolean implicitCall,
		boolean canBePrefixed,
		Binding[] missingElements,
		int[] missingElementsStarts,
		int[] missingElementsEnds,
		boolean missingElementsHaveProblems,
		char[] castedReceiver,
		int receiverStart,
		int receiverEnd) {

		ObjectVector newFieldsFound = new ObjectVector();
		// Inherited fields which are hidden by subclasses are filtered out
		// No visibility checks can be performed without the scope & invocationSite

		int fieldLength = fieldName.length;
		next : for (int f = fields.length; --f >= 0;) {
			FieldBinding field = fields[f];

			if (field.isSynthetic())	continue next;

			if (onlyStaticFields && !field.isStatic()) continue next;

			if (fieldLength > field.name.length) continue next;

			if (!CharOperation.prefixEquals(fieldName, field.name, false /* ignore case */)
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(fieldName, field.name)))	continue next;

			if (this.options.checkDeprecation &&
					field.isViewedAsDeprecated() &&
					!scope.isDefinedInSameUnit(field.declaringClass))
				continue next;

			if (this.options.checkVisibility
				&& !field.canBeSeenBy(receiverType, invocationSite, scope))	continue next;
			
			// don't propose array types in case expression
			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=195346
			if (this.assistNodeIsInsideCase && field.type instanceof ArrayBinding)
				continue next;
			
			int ptr = this.uninterestingBindingsPtr;
			// Cases where the binding is uninteresting eg. for completion occurring inside a field declaration,
			// the field binding is uninteresting and shouldn't be proposed.
			while (ptr >= 0) {
				if (this.uninterestingBindings[ptr] == field) {
					continue next;
				}
				ptr--;
			}

			boolean prefixRequired = false;

			for (int i = fieldsFound.size; --i >= 0;) {
				Object[] other = (Object[])fieldsFound.elementAt(i);
				FieldBinding otherField = (FieldBinding) other[0];
				ReferenceBinding otherReceiverType = (ReferenceBinding) other[1];
				if (field == otherField && receiverType == otherReceiverType)
					continue next;
				if (CharOperation.equals(field.name, otherField.name, true)) {
					if (field.declaringClass.isSuperclassOf(otherField.declaringClass))
						continue next;
					if (otherField.declaringClass.isInterface()) {
						if (field.declaringClass == scope.getJavaLangObject())
							continue next;
						if (field.declaringClass.implementsInterface(otherField.declaringClass, true))
							continue next;
					}
					if (field.declaringClass.isInterface())
						if (otherField.declaringClass.implementsInterface(field.declaringClass, true))
							continue next;
					if(canBePrefixed) {
						prefixRequired = true;
					} else {
						continue next;
					}
				}
			}

			for (int l = localsFound.size; --l >= 0;) {
				LocalVariableBinding local = (LocalVariableBinding) localsFound.elementAt(l);

				if (CharOperation.equals(field.name, local.name, true)) {
					SourceTypeBinding declarationType = scope.enclosingSourceType();
					if (declarationType.isAnonymousType() && declarationType != invocationScope.enclosingSourceType()) {
						continue next;
					}
					if(canBePrefixed) {
						prefixRequired = true;
					} else {
						continue next;
					}
					break;
				}
			}

			newFieldsFound.add(new Object[]{field, receiverType});

			char[] completion = field.name;

			if(prefixRequired || this.options.forceImplicitQualification){
				char[] prefix = computePrefix(scope.enclosingSourceType(), invocationScope.enclosingSourceType(), field.isStatic());
				completion = CharOperation.concat(prefix,completion,'.');
			}


			if (castedReceiver != null) {
				completion = CharOperation.concat(castedReceiver, completion);
			}

			// Special case for javadoc completion
			if (this.assistNodeInJavadoc > 0) {
				if (invocationSite instanceof CompletionOnJavadocFieldReference) {
					CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) invocationSite;
					if (fieldRef.receiver.isThis()) {
						if (fieldRef.completeInText()) {
							completion = CharOperation.concat(new char[] { '#' }, field.name);
						}
					} else if (fieldRef.completeInText()) {
						if (fieldRef.receiver instanceof JavadocSingleTypeReference) {
							JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) fieldRef.receiver;
							completion = CharOperation.concat(typeRef.token, field.name, '#');
						} else if (fieldRef.receiver instanceof JavadocQualifiedTypeReference) {
							JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) fieldRef.receiver;
							completion = CharOperation.concat(CharOperation.concatWith(typeRef.tokens, '.'), field.name, '#');
						}
					}
				}
			}

			int relevance = computeBaseRelevance();
			relevance += computeRelevanceForResolution();
			relevance += computeRelevanceForInterestingProposal(field);
			relevance += computeRelevanceForCaseMatching(fieldName, field.name);
			relevance += computeRelevanceForExpectingType(field.type);
			relevance += computeRelevanceForEnumConstant(field.type);
			relevance += computeRelevanceForStatic(onlyStaticFields, field.isStatic());
			relevance += computeRelevanceForFinal(this.assistNodeIsInsideCase, field.isFinal());
			relevance += computeRelevanceForQualification(prefixRequired);
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
			if (onlyStaticFields && this.insideQualifiedReference) {
				relevance += computeRelevanceForInheritance(receiverType, field.declaringClass);
			}
			if (missingElements != null) {
				relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
			}

			this.noProposal = false;
			if (castedReceiver == null) {
				// Standard proposal
				if (!this.isIgnored(CompletionProposal.FIELD_REF, missingElements != null) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
					proposal.setDeclarationSignature(getSignature(field.declaringClass));
					proposal.setSignature(getSignature(field.type));
					proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
					proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
					proposal.setPackageName(field.type.qualifiedPackageName());
					proposal.setTypeName(field.type.qualifiedSourceName());
					proposal.setName(field.name);
					if (missingElements != null) {
						CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
						for (int i = 0; i < missingElements.length; i++) {
							subProposals[i] =
								createRequiredTypeProposal(
										missingElements[i],
										missingElementsStarts[i],
										missingElementsEnds[i],
										relevance);
						}
						proposal.setRequiredProposals(subProposals);
					}
					proposal.setCompletion(completion);
					proposal.setFlags(field.modifiers);
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
					proposal.setRelevance(relevance);
					this.requestor.accept(proposal);
					if(DEBUG) {
						this.printDebug(proposal);
					}
				}

				// Javadoc completions
				if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_FIELD_REF)) {
					char[] javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_LINK);
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_FIELD_REF, this.actualCompletionPosition);
					proposal.setDeclarationSignature(getSignature(field.declaringClass));
					proposal.setSignature(getSignature(field.type));
					proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
					proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
					proposal.setPackageName(field.type.qualifiedPackageName());
					proposal.setTypeName(field.type.qualifiedSourceName());
					proposal.setName(field.name);
					proposal.setCompletion(javadocCompletion);
					proposal.setFlags(field.modifiers);
					int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
					proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
					proposal.setRelevance(relevance+R_INLINE_TAG);
					this.requestor.accept(proposal);
					if(DEBUG) {
						this.printDebug(proposal);
					}
					// Javadoc value completion for static fields
					if (field.isStatic() && !this.requestor.isIgnored(CompletionProposal.JAVADOC_VALUE_REF)) {
						javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_VALUE);
						InternalCompletionProposal valueProposal = createProposal(CompletionProposal.JAVADOC_VALUE_REF, this.actualCompletionPosition);
						valueProposal.setDeclarationSignature(getSignature(field.declaringClass));
						valueProposal.setSignature(getSignature(field.type));
						valueProposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
						valueProposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
						valueProposal.setPackageName(field.type.qualifiedPackageName());
						valueProposal.setTypeName(field.type.qualifiedSourceName());
						valueProposal.setName(field.name);
						valueProposal.setCompletion(javadocCompletion);
						valueProposal.setFlags(field.modifiers);
						valueProposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
						valueProposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
						valueProposal.setRelevance(relevance+R_VALUE_TAG);
						this.requestor.accept(valueProposal);
						if(DEBUG) {
							this.printDebug(valueProposal);
						}
					}
				}
			} else {
				if(!this.isIgnored(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, missingElements != null)) {
					InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, this.actualCompletionPosition);
					proposal.setDeclarationSignature(getSignature(field.declaringClass));
					proposal.setSignature(getSignature(field.type));
					proposal.setReceiverSignature(getSignature(receiverType));
					proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
					proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
					proposal.setPackageName(field.type.qualifiedPackageName());
					proposal.setTypeName(field.type.qualifiedSourceName());
					proposal.setName(field.name);
					if (missingElements != null) {
						CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
						for (int i = 0; i < missingElements.length; i++) {
							subProposals[i] =
								createRequiredTypeProposal(
										missingElements[i],
										missingElementsStarts[i],
										missingElementsEnds[i],
										relevance);
						}
						proposal.setRequiredProposals(subProposals);
					}
					proposal.setCompletion(completion);
					proposal.setFlags(field.modifiers);
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
					proposal.setReceiverRange(receiverStart - this.offset, receiverEnd - this.offset);
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
					proposal.setRelevance(relevance);
					this.requestor.accept(proposal);
					if(DEBUG) {
						this.printDebug(proposal);
					}
				}
			}
		}

		fieldsFound.addAll(newFieldsFound);
	}
	private void findFields(
		char[] fieldName,
		ReferenceBinding receiverType,
		Scope scope,
		ObjectVector fieldsFound,
		ObjectVector localsFound,
		boolean onlyStaticFields,
		InvocationSite invocationSite,
		Scope invocationScope,
		boolean implicitCall,
		boolean canBePrefixed,
		Binding[] missingElements,
		int[] missingElementsStarts,
		int[] missingElementsEnds,
		boolean missingElementsHaveProblems,
		char[] castedReceiver,
		int receiverStart,
		int receiverEnd) {

		boolean notInJavadoc = this.assistNodeInJavadoc == 0;
		if (fieldName == null && notInJavadoc)
			return;

		ReferenceBinding currentType = receiverType;
		ReferenceBinding[] interfacesToVisit = null;
		int nextPosition = 0;
		do {
			ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
			if (notInJavadoc && itsInterfaces != Binding.NO_SUPERINTERFACES) {
				if (interfacesToVisit == null) {
					interfacesToVisit = itsInterfaces;
					nextPosition = interfacesToVisit.length;
				} else {
					int itsLength = itsInterfaces.length;
					if (nextPosition + itsLength >= interfacesToVisit.length)
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
					nextInterface : for (int a = 0; a < itsLength; a++) {
						ReferenceBinding next = itsInterfaces[a];
						for (int b = 0; b < nextPosition; b++)
							if (next == interfacesToVisit[b]) continue nextInterface;
						interfacesToVisit[nextPosition++] = next;
					}
				}
			}

			FieldBinding[] fields = currentType.availableFields();
			if(fields != null && fields.length > 0) {
				findFields(
					fieldName,
					fields,
					scope,
					fieldsFound,
					localsFound,
					onlyStaticFields,
					receiverType,
					invocationSite,
					invocationScope,
					implicitCall,
					canBePrefixed,
					missingElements,
					missingElementsStarts,
					missingElementsEnds,
					missingElementsHaveProblems,
					castedReceiver,
					receiverStart,
					receiverEnd);
			}
			currentType = currentType.superclass();
		} while (notInJavadoc && currentType != null);

		if (notInJavadoc && interfacesToVisit != null) {
			for (int i = 0; i < nextPosition; i++) {
				ReferenceBinding anInterface = interfacesToVisit[i];
				FieldBinding[] fields = anInterface.availableFields();
				if(fields !=  null) {
					findFields(
						fieldName,
						fields,
						scope,
						fieldsFound,
						localsFound,
						onlyStaticFields,
						receiverType,
						invocationSite,
						invocationScope,
						implicitCall,
						canBePrefixed,
						missingElements,
						missingElementsStarts,
						missingElementsEnds,
						missingElementsHaveProblems,
						castedReceiver,
						receiverStart,
						receiverEnd);
				}

				ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
				if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
					int itsLength = itsInterfaces.length;
					if (nextPosition + itsLength >= interfacesToVisit.length)
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
					nextInterface : for (int a = 0; a < itsLength; a++) {
						ReferenceBinding next = itsInterfaces[a];
						for (int b = 0; b < nextPosition; b++)
							if (next == interfacesToVisit[b]) continue nextInterface;
						interfacesToVisit[nextPosition++] = next;
					}
				}
			}
		}
	}

	protected void findFieldsAndMethods(
		char[] token,
		TypeBinding receiverType,
		Scope scope,
		ObjectVector fieldsFound,
		ObjectVector methodsFound,
		InvocationSite invocationSite,
		Scope invocationScope,
		boolean implicitCall,
		boolean superCall,
		Binding[] missingElements,
		int[] missingElementsStarts,
		int[] missingElementsEnds,
		boolean missingElementsHaveProblems,
		char[] castedReceiver,
		int receiverStart,
		int receiverEnd) {

		if (token == null)
			return;

		if (receiverType.isBaseType())
			return; // nothing else is possible with base types

		boolean proposeField =
			castedReceiver == null ?
					!this.isIgnored(CompletionProposal.FIELD_REF, missingElements != null) :
					!this.isIgnored(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, missingElements != null) ;
		boolean proposeMethod =
			castedReceiver == null ?
					!this.isIgnored(CompletionProposal.METHOD_REF, missingElements != null) :
					!this.isIgnored(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, missingElements != null);

		if (receiverType.isArrayType()) {
			if (proposeField
				&& token.length <= lengthField.length
				&& CharOperation.prefixEquals(token, lengthField, false /* ignore case */
			)) {

				int relevance = computeBaseRelevance();
				relevance += computeRelevanceForResolution();
				relevance += computeRelevanceForInterestingProposal();
				relevance += computeRelevanceForCaseMatching(token,lengthField);
				relevance += computeRelevanceForExpectingType(TypeBinding.INT);
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for length field
				if (missingElements != null) {
					relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
				}
				this.noProposal = false;
				if (castedReceiver == null) {
					if(!isIgnored(CompletionProposal.FIELD_REF, missingElements != null)) {
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
						proposal.setDeclarationSignature(getSignature(receiverType));
						proposal.setSignature(INT_SIGNATURE);
						proposal.setTypeName(INT);
						proposal.setName(lengthField);
						if (missingElements != null) {
							CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
							for (int i = 0; i < missingElements.length; i++) {
								subProposals[i] =
									createRequiredTypeProposal(
											missingElements[i],
											missingElementsStarts[i],
											missingElementsEnds[i],
											relevance);
							}
							proposal.setRequiredProposals(subProposals);
						}
						proposal.setCompletion(lengthField);
						proposal.setFlags(Flags.AccPublic);
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
						proposal.setRelevance(relevance);
						this.requestor.accept(proposal);
						if(DEBUG) {
							this.printDebug(proposal);
						}
					}
				} else {
					char[] completion = CharOperation.concat(castedReceiver, lengthField);

					if(!this.isIgnored(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, missingElements != null)) {
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, this.actualCompletionPosition);
						proposal.setDeclarationSignature(getSignature(receiverType));
						proposal.setSignature(INT_SIGNATURE);
						proposal.setReceiverSignature(getSignature(receiverType));
						proposal.setTypeName(INT);
						proposal.setName(lengthField);
						if (missingElements != null) {
							CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
							for (int i = 0; i < missingElements.length; i++) {
								subProposals[i] =
									createRequiredTypeProposal(
											missingElements[i],
											missingElementsStarts[i],
											missingElementsEnds[i],
											relevance);
							}
							proposal.setRequiredProposals(subProposals);
						}
						proposal.setCompletion(completion);
						proposal.setFlags(Flags.AccPublic);
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
						proposal.setReceiverRange(receiverStart - this.offset, receiverEnd - this.offset);
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
						proposal.setRelevance(relevance);
						this.requestor.accept(proposal);
						if(DEBUG) {
							this.printDebug(proposal);
						}
					}
				}
			}
			if (proposeMethod
				&& token.length <= cloneMethod.length
				&& CharOperation.prefixEquals(token, cloneMethod, false /* ignore case */)
			) {
				ReferenceBinding objectRef = scope.getJavaLangObject();

				int relevance = computeBaseRelevance();
				relevance += computeRelevanceForResolution();
				relevance += computeRelevanceForInterestingProposal();
				relevance += computeRelevanceForCaseMatching(token, cloneMethod);
				relevance += computeRelevanceForExpectingType(objectRef);
				relevance += computeRelevanceForStatic(false, false);
				relevance += computeRelevanceForQualification(false);
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for clone() method
				if (missingElements != null) {
					relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
				}
				char[] completion;
				if (this.source != null
					&& this.source.length > this.endPosition
					&& this.source[this.endPosition] == '(') {
					completion = cloneMethod;
					} else {
					completion = CharOperation.concat(cloneMethod, new char[] { '(', ')' });
				}

				if (castedReceiver != null) {
					completion = CharOperation.concat(castedReceiver, completion);
				}

				this.noProposal = false;
				if (castedReceiver == null) {
					if (!this.isIgnored(CompletionProposal.METHOD_REF, missingElements != null)) {
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
						proposal.setDeclarationSignature(getSignature(receiverType));
						proposal.setSignature(
								this.compilerOptions.sourceLevel > ClassFileConstants.JDK1_4 && receiverType.isArrayType() ?
										createMethodSignature(
												CharOperation.NO_CHAR_CHAR,
												CharOperation.NO_CHAR_CHAR,
												getSignature(receiverType)) :
										createMethodSignature(
												CharOperation.NO_CHAR_CHAR,
												CharOperation.NO_CHAR_CHAR,
												CharOperation.concatWith(JAVA_LANG, '.'),
												OBJECT));
						//proposal.setOriginalSignature(null);
						//proposal.setDeclarationPackageName(null);
						//proposal.setDeclarationTypeName(null);
						//proposal.setParameterPackageNames(null);
						//proposal.setParameterTypeNames(null);
						proposal.setPackageName(CharOperation.concatWith(JAVA_LANG, '.'));
						proposal.setTypeName(OBJECT);
						proposal.setName(cloneMethod);
						if (missingElements != null) {
							CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
							for (int i = 0; i < missingElements.length; i++) {
								subProposals[i] =
									createRequiredTypeProposal(
											missingElements[i],
											missingElementsStarts[i],
											missingElementsEnds[i],
											relevance);
							}
							proposal.setRequiredProposals(subProposals);
						}
						proposal.setCompletion(completion);
						proposal.setFlags(Flags.AccPublic);
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
						proposal.setRelevance(relevance);
						this.requestor.accept(proposal);
						if(DEBUG) {
							this.printDebug(proposal);
						}
					}
					methodsFound.add(new Object[]{objectRef.getMethods(cloneMethod)[0], objectRef});
				} else {
					if(!this.isIgnored(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, missingElements != null)) {
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, this.actualCompletionPosition);
						proposal.setDeclarationSignature(getSignature(receiverType));
						proposal.setSignature(
								this.compilerOptions.sourceLevel > ClassFileConstants.JDK1_4 && receiverType.isArrayType() ?
										createMethodSignature(
												CharOperation.NO_CHAR_CHAR,
												CharOperation.NO_CHAR_CHAR,
												getSignature(receiverType)) :
										createMethodSignature(
												CharOperation.NO_CHAR_CHAR,
												CharOperation.NO_CHAR_CHAR,
												CharOperation.concatWith(JAVA_LANG, '.'),
												OBJECT));
						proposal.setReceiverSignature(getSignature(receiverType));
						proposal.setPackageName(CharOperation.concatWith(JAVA_LANG, '.'));
						proposal.setTypeName(OBJECT);
						proposal.setName(cloneMethod);
						if (missingElements != null) {
							CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
							for (int i = 0; i < missingElements.length; i++) {
								subProposals[i] =
									createRequiredTypeProposal(
											missingElements[i],
											missingElementsStarts[i],
											missingElementsEnds[i],
											relevance);
							}
							proposal.setRequiredProposals(subProposals);
						}
						proposal.setCompletion(completion);
						proposal.setFlags(Flags.AccPublic);
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
						proposal.setReceiverRange(receiverStart - this.offset, receiverEnd - this.offset);
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
						proposal.setRelevance(relevance);
						this.requestor.accept(proposal);
						if(DEBUG) {
							this.printDebug(proposal);
						}
					}
				}
			}

			receiverType = scope.getJavaLangObject();
		}
		
		checkCancel();
		
		if(proposeField) {
			findFields(
				token,
				(ReferenceBinding) receiverType,
				scope,
				fieldsFound,
				new ObjectVector(),
				false,
				invocationSite,
				invocationScope,
				implicitCall,
				false,
				missingElements,
				missingElementsStarts,
				missingElementsEnds,
				missingElementsHaveProblems,
				castedReceiver,
				receiverStart,
				receiverEnd);
		}

		if(proposeMethod) {
			findMethods(
				token,
				null,
				null,
				(ReferenceBinding) receiverType,
				scope,
				methodsFound,
				false,
				false,
				invocationSite,
				invocationScope,
				implicitCall,
				superCall,
				false,
				missingElements,
				missingElementsStarts,
				missingElementsEnds,
				missingElementsHaveProblems,
				castedReceiver,
				receiverStart,
				receiverEnd);
		}
	}

	protected void findFieldsAndMethodsFromAnotherReceiver(
			char[] token,
			TypeReference receiverType,
			Scope scope,
			ObjectVector fieldsFound,
			ObjectVector methodsFound,
			InvocationSite invocationSite,
			Scope invocationScope,
			boolean implicitCall,
			boolean superCall,
			Binding[] missingElements,
			int[] missingElementsStarts,
			int[] missingElementsEnds,
			boolean missingElementsHaveProblems,
			char[][] receiverName,
			int receiverStart,
			int receiverEnd) {

		if (receiverType.resolvedType == null) return;

		TypeBinding receiverTypeBinding = receiverType.resolvedType;
		char[] castedReceiver = null;

		char[] castedTypeChars = CharOperation.concatWith(receiverType.getTypeName(), '.');
		if(this.source != null) {
			int memberRefStart = this.startPosition;

			char[] receiverChars = CharOperation.subarray(this.source, receiverStart, receiverEnd);
			char[] dotChars = CharOperation.subarray(this.source, receiverEnd, memberRefStart);

			castedReceiver =
				CharOperation.concat(
					CharOperation.concat(
						'(',
						CharOperation.concat(
							CharOperation.concat('(', castedTypeChars, ')'),
							receiverChars),
						')'),
					dotChars);
		} else {
			castedReceiver =
				CharOperation.concat(
					CharOperation.concat(
						'(',
						CharOperation.concat(
							CharOperation.concat('(', castedTypeChars, ')'),
							CharOperation.concatWith(receiverName, '.')),
						')'),
					DOT);
		}

		if (castedReceiver == null) return;

		int oldStartPosition = this.startPosition;
		this.startPosition = receiverStart;

		findFieldsAndMethods(
				token,
				receiverTypeBinding,
				scope,
				fieldsFound,
				methodsFound,
				invocationSite,
				invocationScope,
				implicitCall,
				superCall,
				missingElements,
				missingElementsStarts,
				missingElementsEnds,
				missingElementsHaveProblems,
				castedReceiver,
				receiverStart,
				receiverEnd);

		this.startPosition = oldStartPosition;
	}
	private void findFieldsAndMethodsFromCastedReceiver(
			ASTNode enclosingNode,
			Binding qualifiedBinding,
			Scope scope,
			ObjectVector fieldsFound,
			ObjectVector methodsFound,
			InvocationSite invocationSite,
			Scope invocationScope,
			Expression receiver) {

		if (enclosingNode == null || !(enclosingNode instanceof IfStatement)) return;

		IfStatement ifStatement = (IfStatement)enclosingNode;
		while (true) {
			if (!(ifStatement.condition instanceof InstanceOfExpression)) return;
	
			InstanceOfExpression instanceOfExpression = (InstanceOfExpression) ifStatement.condition;
	
			TypeReference instanceOfType = instanceOfExpression.type;
	
			if (instanceOfType.resolvedType == null) return;
	
			boolean findFromAnotherReceiver = false;
	
			char[][] receiverName = null;
			int receiverStart = -1;
			int receiverEnd = -1;
	
			if (receiver instanceof QualifiedNameReference) {
				QualifiedNameReference qualifiedNameReference = (QualifiedNameReference) receiver;
	
				receiverName = qualifiedNameReference.tokens;
	
				if (receiverName.length != 1) return;
	
				receiverStart = (int) (qualifiedNameReference.sourcePositions[0] >>> 32);
				receiverEnd = (int) qualifiedNameReference.sourcePositions[qualifiedNameReference.tokens.length - 1] + 1;
	
				// if (local instanceof X) local.|
				// if (field instanceof X) field.|
				if (instanceOfExpression.expression instanceof SingleNameReference &&
						((SingleNameReference)instanceOfExpression.expression).binding == qualifiedBinding &&
						(qualifiedBinding instanceof LocalVariableBinding || qualifiedBinding instanceof FieldBinding)) {
					findFromAnotherReceiver = true;
				}
	
				// if (this.field instanceof X) field.|
				if (instanceOfExpression.expression instanceof FieldReference) {
					FieldReference fieldReference = (FieldReference)instanceOfExpression.expression;
	
					if (fieldReference.receiver instanceof ThisReference &&
							qualifiedBinding instanceof FieldBinding &&
							fieldReference.binding == qualifiedBinding) {
								findFromAnotherReceiver = true;
					}
				}
			} else if (receiver instanceof FieldReference) {
				FieldReference fieldReference1 = (FieldReference) receiver;
	
				receiverStart = fieldReference1.sourceStart;
				receiverEnd = fieldReference1.sourceEnd + 1;
	
				if (fieldReference1.receiver instanceof ThisReference) {
	
					receiverName = new char[][] {THIS, fieldReference1.token};
	
					// if (field instanceof X) this.field.|
					if (instanceOfExpression.expression instanceof SingleNameReference &&
							((SingleNameReference)instanceOfExpression.expression).binding == fieldReference1.binding) {
						findFromAnotherReceiver = true;
					}
	
					// if (this.field instanceof X) this.field.|
					if (instanceOfExpression.expression instanceof FieldReference) {
						FieldReference fieldReference2 = (FieldReference)instanceOfExpression.expression;
	
						if (fieldReference2.receiver instanceof ThisReference &&
								fieldReference2.binding == fieldReference1.binding) {
									findFromAnotherReceiver = true;
						}
					}
				}
			}
	
			if (findFromAnotherReceiver) {
				TypeBinding receiverTypeBinding = instanceOfType.resolvedType;
				char[] castedReceiver = null;
	
				char[] castedTypeChars = CharOperation.concatWith(instanceOfType.getTypeName(), '.');
				if(this.source != null) {
					int memberRefStart = this.startPosition;
	
					char[] receiverChars = CharOperation.subarray(this.source, receiverStart, receiverEnd);
					char[] dotChars = CharOperation.subarray(this.source, receiverEnd, memberRefStart);
	
					castedReceiver =
						CharOperation.concat(
							CharOperation.concat(
								'(',
								CharOperation.concat(
									CharOperation.concat('(', castedTypeChars, ')'),
									receiverChars),
								')'),
							dotChars);
				} else {
					castedReceiver =
						CharOperation.concat(
							CharOperation.concat(
								'(',
								CharOperation.concat(
									CharOperation.concat('(', castedTypeChars, ')'),
									CharOperation.concatWith(receiverName, '.')),
								')'),
							DOT);
				}
	
				if (castedReceiver == null) return;
	
				int oldStartPosition = this.startPosition;
				this.startPosition = receiverStart;
	
				findFieldsAndMethods(
						this.completionToken,
						receiverTypeBinding,
						scope,
						fieldsFound,
						methodsFound,
						invocationSite,
						invocationScope,
						false,
						false,
						null,
						null,
						null,
						false,
						castedReceiver,
						receiverStart,
						receiverEnd);
	
				this.startPosition = oldStartPosition;
			}
			// traverse the enclosing node to find the instanceof expression corresponding
			// to the completion node (if any)
			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=304006
			if (ifStatement.thenStatement instanceof IfStatement) {
				ifStatement = (IfStatement) ifStatement.thenStatement;
			} else {
				break;
			}
		}
	}
	private void findFieldsAndMethodsFromFavorites(
			char[] token,
			Scope scope,
			InvocationSite invocationSite,
			Scope invocationScope,
			ObjectVector localsFound,
			ObjectVector fieldsFound,
			ObjectVector methodsFound) {

		ObjectVector methodsFoundFromFavorites = new ObjectVector();

		ImportBinding[] favoriteBindings = getFavoriteReferenceBindings(invocationScope);

		if (favoriteBindings != null && favoriteBindings.length > 0) {
			for (int i = 0; i < favoriteBindings.length; i++) {
				ImportBinding favoriteBinding = favoriteBindings[i];
				switch (favoriteBinding.resolvedImport.kind()) {
					case Binding.FIELD:
						FieldBinding fieldBinding = (FieldBinding) favoriteBinding.resolvedImport;
						findFieldsFromFavorites(
								token,
								new FieldBinding[]{fieldBinding},
								scope,
								fieldsFound,
								localsFound,
								fieldBinding.declaringClass,
								invocationSite,
								invocationScope);
						break;
					case Binding.METHOD:
						MethodBinding methodBinding = (MethodBinding) favoriteBinding.resolvedImport;
						MethodBinding[] methods = methodBinding.declaringClass.availableMethods();
						long range;
						if ((range = ReferenceBinding.binarySearch(methodBinding.selector, methods)) >= 0) {
							int start = (int) range, end = (int) (range >> 32);
							int length = end - start + 1;
							System.arraycopy(methods, start, methods = new MethodBinding[length], 0, length);
						} else {
							methods = Binding.NO_METHODS;
						}
						findLocalMethodsFromFavorites(
								token,
								methods,
								scope,
								methodsFound,
								methodsFoundFromFavorites,
								methodBinding.declaringClass,
								invocationSite,
								invocationScope);
						break;
					case Binding.TYPE:
						ReferenceBinding referenceBinding = (ReferenceBinding) favoriteBinding.resolvedImport;
						if(favoriteBinding.onDemand) {
							findFieldsFromFavorites(
									token,
									referenceBinding.availableFields(),
									scope,
									fieldsFound,
									localsFound,
									referenceBinding,
									invocationSite,
									invocationScope);

							findLocalMethodsFromFavorites(
									token,
									referenceBinding.availableMethods(),
									scope,
									methodsFound,
									methodsFoundFromFavorites,
									referenceBinding,
									invocationSite,
									invocationScope);
						}
						break;
				}
			}
		}

		methodsFound.addAll(methodsFoundFromFavorites);
	}

	private boolean findFieldsAndMethodsFromMissingFieldType(
		char[] token,
		Scope scope,
		InvocationSite invocationSite,
		boolean insideTypeAnnotation) {

		boolean foundSomeFields = false;

		boolean staticsOnly = false;
		Scope currentScope = scope;

		done : while (true) { // done when a COMPILATION_UNIT_SCOPE is found

			switch (currentScope.kind) {

				case Scope.METHOD_SCOPE :
					// handle the error case inside an explicit constructor call (see MethodScope>>findField)
					MethodScope methodScope = (MethodScope) currentScope;
					staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
					break;
				case Scope.CLASS_SCOPE :
					ClassScope classScope = (ClassScope) currentScope;
					SourceTypeBinding enclosingType = classScope.referenceContext.binding;
					if(!insideTypeAnnotation) {

						FieldDeclaration[] fields = classScope.referenceContext.fields;

						int fieldsCount = fields == null ? 0 : fields.length;
						for (int i = 0; i < fieldsCount; i++) {
							FieldDeclaration fieldDeclaration = fields[i];
							if (CharOperation.equals(fieldDeclaration.name, token)) {
								FieldBinding fieldBinding = fieldDeclaration.binding;
								if (fieldBinding == null || fieldBinding.type == null  || (fieldBinding.type.tagBits & TagBits.HasMissingType) != 0) {
									foundSomeFields = true;
									findFieldsAndMethodsFromMissingType(
											fieldDeclaration.type,
											currentScope,
											invocationSite,
											scope);
								}
								break done;
							}
						}
					}
					staticsOnly |= enclosingType.isStatic();
					insideTypeAnnotation = false;
					break;
				case Scope.COMPILATION_UNIT_SCOPE :
					break done;
			}
			currentScope = currentScope.parent;
		}
		return foundSomeFields;
	}

	private void findFieldsAndMethodsFromMissingReturnType(
		char[] token,
		TypeBinding[] arguments,
		Scope scope,
		InvocationSite invocationSite,
		boolean insideTypeAnnotation) {

		boolean staticsOnly = false;
		Scope currentScope = scope;

		done : while (true) { // done when a COMPILATION_UNIT_SCOPE is found

			switch (currentScope.kind) {

				case Scope.METHOD_SCOPE :
					// handle the error case inside an explicit constructor call (see MethodScope>>findField)
					MethodScope methodScope = (MethodScope) currentScope;
					staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
					break;
				case Scope.CLASS_SCOPE :
					ClassScope classScope = (ClassScope) currentScope;
					SourceTypeBinding enclosingType = classScope.referenceContext.binding;
					if(!insideTypeAnnotation) {

						AbstractMethodDeclaration[] methods = classScope.referenceContext.methods;

						int methodsCount = methods == null ? 0 : methods.length;
						for (int i = 0; i < methodsCount; i++) {
							AbstractMethodDeclaration methodDeclaration = methods[i];
							if (methodDeclaration instanceof MethodDeclaration &&
									CharOperation.equals(methodDeclaration.selector, token)) {
								MethodDeclaration method = (MethodDeclaration) methodDeclaration;
								MethodBinding methodBinding = method.binding;
								if (methodBinding == null || methodBinding.returnType == null  || (methodBinding.returnType.tagBits & TagBits.HasMissingType) != 0) {
									Argument[] parameters = method.arguments;
									int parametersLength = parameters == null ? 0 : parameters.length;
									int argumentsLength = arguments == null ? 0 : arguments.length;

									if (parametersLength == 0) {
										if (argumentsLength == 0) {
											findFieldsAndMethodsFromMissingType(
													method.returnType,
													currentScope,
													invocationSite,
													scope);
											break done;
										}
									} else {
										TypeBinding[] parametersBindings;
										if (methodBinding == null) { // since no binding, extra types from type references
											parametersBindings = new TypeBinding[parametersLength];
											for (int j = 0; j < parametersLength; j++) {
												TypeBinding parameterType = parameters[j].type.resolvedType;
												if (!parameterType.isValidBinding() && parameterType.closestMatch() != null) {
													parameterType = parameterType.closestMatch();
												}
												parametersBindings[j] = parameterType;
											}
										} else {
											parametersBindings = methodBinding.parameters;
										}
										if(areParametersCompatibleWith(parametersBindings, arguments, parameters[parametersLength - 1].isVarArgs())) {
											findFieldsAndMethodsFromMissingType(
													method.returnType,
													currentScope,
													invocationSite,
													scope);
											break done;
										}
									}
								}

							}
						}
					}
					staticsOnly |= enclosingType.isStatic();
					insideTypeAnnotation = false;
					break;
				case Scope.COMPILATION_UNIT_SCOPE :
					break done;
			}
			currentScope = currentScope.parent;
		}
	}

	private void findFieldsAndMethodsFromMissingType(
			TypeReference typeRef,
			final Scope scope,
			final InvocationSite invocationSite,
			final Scope invocationScope) {
		MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this);
		MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor =
			new MissingTypesGuesser.GuessedTypeRequestor() {
				public void accept(
						TypeBinding guessedType,
						Binding[] missingElements,
						int[] missingElementsStarts,
						int[] missingElementsEnds,
						boolean hasProblems) {
					findFieldsAndMethods(
						CompletionEngine.this.completionToken,
						guessedType,
						scope,
						new ObjectVector(),
						new ObjectVector(),
						invocationSite,
						invocationScope,
						false,
						false,
						missingElements,
						missingElementsStarts,
						missingElementsEnds,
						hasProblems,
						null,
						-1,
						-1);

				}
			};
		missingTypesConverter.guess(typeRef, scope, substitutionRequestor);
	}

	private void findFieldsAndMethodsFromStaticImports(
			char[] token,
			Scope scope,
			InvocationSite invocationSite,
			Scope invocationScope,
			boolean exactMatch,
			boolean insideAnnotationAttribute,
			ObjectVector localsFound,
			ObjectVector fieldsFound,
			ObjectVector methodsFound,
			boolean proposeField,
			boolean proposeMethod) {
		// search in static import
		ImportBinding[] importBindings = scope.compilationUnitScope().imports;
		for (int i = 0; i < importBindings.length; i++) {
			ImportBinding importBinding = importBindings[i];
			if(importBinding.isValidBinding() && importBinding.isStatic()) {
				Binding binding = importBinding.resolvedImport;
				if(binding != null && binding.isValidBinding()) {
					if(importBinding.onDemand) {
						if((binding.kind() & Binding.TYPE) != 0) {
							if(proposeField) {
								findFields(
									token,
									(ReferenceBinding)binding,
									scope,
									fieldsFound,
									localsFound,
									true,
									invocationSite,
									invocationScope,
									true,
									false,
									null,
									null,
									null,
									false,
									null,
									-1,
									-1);
							}
							if(proposeMethod && !insideAnnotationAttribute) {
								findMethods(
									token,
									null,
									null,
									(ReferenceBinding)binding,
									scope,
									methodsFound,
									true,
									exactMatch,
									invocationSite,
									invocationScope,
									true,
									false,
									false,
									null,
									null,
									null,
									false,
									null,
									-1,
									-1);
							}
						}
					} else {
						if ((binding.kind() & Binding.FIELD) != 0) {
							if(proposeField) {
									findFields(
											token,
											new FieldBinding[]{(FieldBinding)binding},
											scope,
											fieldsFound,
											localsFound,
											true,
											((FieldBinding)binding).declaringClass,
											invocationSite,
											invocationScope,
											true,
											false,
											null,
											null,
											null,
											false,
											null,
											-1,
											-1);
							}
						} else if ((binding.kind() & Binding.METHOD) != 0) {
							if(proposeMethod && !insideAnnotationAttribute) {
								MethodBinding methodBinding = (MethodBinding)binding;
								if ((exactMatch && CharOperation.equals(token, methodBinding.selector)) ||
										!exactMatch && CharOperation.prefixEquals(token, methodBinding.selector) ||
										(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, methodBinding.selector))) {
									findLocalMethodsFromStaticImports(
											token,
											methodBinding.declaringClass.getMethods(methodBinding.selector),
											scope,
											exactMatch,
											methodsFound,
											methodBinding.declaringClass,
											invocationSite);
								}
							}
						}
					}
				}
			}
		}
	}

	private void findFieldsFromFavorites(
			char[] fieldName,
			FieldBinding[] fields,
			Scope scope,
			ObjectVector fieldsFound,
			ObjectVector localsFound,
			ReferenceBinding receiverType,
			InvocationSite invocationSite,
			Scope invocationScope) {

		char[] typeName = CharOperation.concatWith(receiverType.compoundName, '.');

		int fieldLength = fieldName.length;
		next : for (int f = fields.length; --f >= 0;) {
			FieldBinding field = fields[f];

			if (field.isSynthetic())	continue next;

			// only static fields must be proposed
			if (!field.isStatic()) continue next;

			if (fieldLength > field.name.length) continue next;

			if (!CharOperation.prefixEquals(fieldName, field.name, false /* ignore case */)
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(fieldName, field.name)))	continue next;

			if (this.options.checkDeprecation &&
					field.isViewedAsDeprecated() &&
					!scope.isDefinedInSameUnit(field.declaringClass))
				continue next;

			if (this.options.checkVisibility
				&& !field.canBeSeenBy(receiverType, invocationSite, scope))	continue next;

			for (int i = fieldsFound.size; --i >= 0;) {
				Object[] other = (Object[])fieldsFound.elementAt(i);
				FieldBinding otherField = (FieldBinding) other[0];

				if (field == otherField) continue next;
			}

			fieldsFound.add(new Object[]{field, receiverType});

			int relevance = computeBaseRelevance();
			relevance += computeRelevanceForResolution();
			relevance += computeRelevanceForInterestingProposal(field);
			relevance += computeRelevanceForCaseMatching(fieldName, field.name);
			relevance += computeRelevanceForExpectingType(field.type);
			relevance += computeRelevanceForEnumConstant(field.type);
			relevance += computeRelevanceForStatic(true, true);
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);

			CompilationUnitDeclaration cu = this.unitScope.referenceContext;
			int importStart = cu.types[0].declarationSourceStart;
			int importEnd = importStart;

			this.noProposal = false;

			if (this.compilerOptions.complianceLevel < ClassFileConstants.JDK1_5 ||
					!this.options.suggestStaticImport) {
				if (!this.isIgnored(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_IMPORT)) {
					char[] completion = CharOperation.concat(receiverType.sourceName, field.name, '.');

					InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
					proposal.setDeclarationSignature(getSignature(field.declaringClass));
					proposal.setSignature(getSignature(field.type));
					proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
					proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
					proposal.setPackageName(field.type.qualifiedPackageName());
					proposal.setTypeName(field.type.qualifiedSourceName());
					proposal.setName(field.name);
					proposal.setCompletion(completion);
					proposal.setFlags(field.modifiers);
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
					proposal.setRelevance(relevance);

					char[] typeImportCompletion = createImportCharArray(typeName, false, false);

					InternalCompletionProposal typeImportProposal = createProposal(CompletionProposal.TYPE_IMPORT, this.actualCompletionPosition);
					typeImportProposal.nameLookup = this.nameEnvironment.nameLookup;
					typeImportProposal.completionEngine = this;
					char[] packageName = receiverType.qualifiedPackageName();
					typeImportProposal.setDeclarationSignature(packageName);
					typeImportProposal.setSignature(getSignature(receiverType));
					typeImportProposal.setPackageName(packageName);
					typeImportProposal.setTypeName(receiverType.qualifiedSourceName());
					typeImportProposal.setCompletion(typeImportCompletion);
					typeImportProposal.setFlags(receiverType.modifiers);
					typeImportProposal.setAdditionalFlags(CompletionFlags.Default);
					typeImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
					typeImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset);
					typeImportProposal.setRelevance(relevance);

					proposal.setRequiredProposals(new CompletionProposal[]{typeImportProposal});

					this.requestor.accept(proposal);
					if(DEBUG) {
						this.printDebug(proposal);
					}
				}
			} else {
				if (!this.isIgnored(CompletionProposal.FIELD_REF, CompletionProposal.FIELD_IMPORT)) {
					char[] completion = field.name;

					InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
					proposal.setDeclarationSignature(getSignature(field.declaringClass));
					proposal.setSignature(getSignature(field.type));
					proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
					proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
					proposal.setPackageName(field.type.qualifiedPackageName());
					proposal.setTypeName(field.type.qualifiedSourceName());
					proposal.setName(field.name);
					proposal.setCompletion(completion);
					proposal.setFlags(field.modifiers);
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
					proposal.setRelevance(relevance);

					char[] fieldImportCompletion = createImportCharArray(CharOperation.concat(typeName, field.name, '.'), true, false);

					InternalCompletionProposal fieldImportProposal = createProposal(CompletionProposal.FIELD_IMPORT, this.actualCompletionPosition);
					fieldImportProposal.setDeclarationSignature(getSignature(field.declaringClass));
					fieldImportProposal.setSignature(getSignature(field.type));
					fieldImportProposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
					fieldImportProposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
					fieldImportProposal.setPackageName(field.type.qualifiedPackageName());
					fieldImportProposal.setTypeName(field.type.qualifiedSourceName());
					fieldImportProposal.setName(field.name);
					fieldImportProposal.setCompletion(fieldImportCompletion);
					fieldImportProposal.setFlags(field.modifiers);
					fieldImportProposal.setAdditionalFlags(CompletionFlags.StaticImport);
					fieldImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
					fieldImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset);
					fieldImportProposal.setRelevance(relevance);

					proposal.setRequiredProposals(new CompletionProposal[]{fieldImportProposal});

					this.requestor.accept(proposal);
					if(DEBUG) {
						this.printDebug(proposal);
					}
				}
			}
		}
	}
	private void findImplicitMessageSends(
		char[] token,
		TypeBinding[] argTypes,
		Scope scope,
		InvocationSite invocationSite,
		Scope invocationScope,
		ObjectVector methodsFound) {

		if (token == null)
			return;

		boolean staticsOnly = false;
		// need to know if we're in a static context (or inside a constructor)

		done : while (true) { // done when a COMPILATION_UNIT_SCOPE is found

			switch (scope.kind) {

				case Scope.METHOD_SCOPE :
					// handle the error case inside an explicit constructor call (see MethodScope>>findField)
					MethodScope methodScope = (MethodScope) scope;
					staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
					break;

				case Scope.CLASS_SCOPE :
					ClassScope classScope = (ClassScope) scope;
					SourceTypeBinding enclosingType = classScope.referenceContext.binding;
					findMethods(
						token,
						null,
						argTypes,
						enclosingType,
						classScope,
						methodsFound,
						staticsOnly,
						true,
						invocationSite,
						invocationScope,
						true,
						false,
						true,
						null,
						null,
						null,
						false,
						null,
						-1,
						-1);
					staticsOnly |= enclosingType.isStatic();
					break;

				case Scope.COMPILATION_UNIT_SCOPE :
					break done;
			}
			scope = scope.parent;
		}
	}
	private void findImports(CompletionOnImportReference importReference, boolean findMembers) {
		char[][] tokens = importReference.tokens;

		char[] importName = CharOperation.concatWith(tokens, '.');

		if (importName.length == 0)
			return;

		char[] lastToken = tokens[tokens.length - 1];
		if(lastToken != null && lastToken.length == 0)
			importName = CharOperation.concat(importName, new char[]{'.'});

		this.resolvingImports = true;
		this.resolvingStaticImports = importReference.isStatic();

		this.completionToken =  lastToken;
		this.qualifiedCompletionToken = importName;

		// want to replace the existing .*;
		if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
			int oldStart = this.startPosition;
			int oldEnd = this.endPosition;
			setSourceRange(
				importReference.sourceStart,
				importReference.declarationSourceEnd);
			this.nameEnvironment.findPackages(importName, this);
			setSourceRange(
				oldStart,
				oldEnd - 1,
				false);
		}
		if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
			this.foundTypesCount = 0;
			this.nameEnvironment.findTypes(
					importName,
					findMembers,
					this.options.camelCaseMatch,
					IJavaSearchConstants.TYPE,
					this,
					this.monitor);
			acceptTypes(null);
		}
	}

	private void findImportsOfMemberTypes(char[] typeName,	ReferenceBinding ref, boolean onlyStatic) {
		ReferenceBinding[] memberTypes = ref.memberTypes();

		int typeLength = typeName.length;
		next : for (int m = memberTypes.length; --m >= 0;) {
			ReferenceBinding memberType = memberTypes[m];
			//		if (!wantClasses && memberType.isClass()) continue next;
			//		if (!wantInterfaces && memberType.isInterface()) continue next;

			if (onlyStatic && !memberType.isStatic())
				continue next;

			if (typeLength > memberType.sourceName.length)
				continue next;

			if (!CharOperation.prefixEquals(typeName, memberType.sourceName, false/* ignore case */)
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, memberType.sourceName)))
				continue next;

			if (this.options.checkDeprecation && memberType.isViewedAsDeprecated()) continue next;

			if (this.options.checkVisibility
				&& !memberType.canBeSeenBy(this.unitScope.fPackage))
				continue next;

			char[] completionName = CharOperation.concat(memberType.sourceName, SEMICOLON);

			int relevance = computeBaseRelevance();
			relevance += computeRelevanceForResolution();
			relevance += computeRelevanceForInterestingProposal();
			relevance += computeRelevanceForCaseMatching(typeName, memberType.sourceName);
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);

			if (memberType.isClass()) {
				relevance += computeRelevanceForClass();
			} else if(memberType.isEnum()) {
				relevance += computeRelevanceForEnum();
			} else if (memberType.isInterface()) {
				relevance += computeRelevanceForInterface();
			}
			this.noProposal = false;
			if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
				createTypeProposal(
						memberType,
						memberType.qualifiedSourceName(),
						IAccessRule.K_ACCESSIBLE,
						completionName,
						relevance,
						null,
						null,
						null,
						false);
			}
		}
	}

	private void findImportsOfStaticFields(char[] fieldName, ReferenceBinding ref) {
		FieldBinding[] fields = ref.availableFields();

		int fieldLength = fieldName.length;
		next : for (int m = fields.length; --m >= 0;) {
			FieldBinding field = fields[m];

			if (fieldLength > field.name.length)
				continue next;

			if (field.isSynthetic())
				continue next;

			if (!field.isStatic())
				continue next;

			if (!CharOperation.prefixEquals(fieldName, field.name, false/* ignore case */)
				&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(fieldName, field.name)))
				continue next;

			if (this.options.checkDeprecation && field.isViewedAsDeprecated()) continue next;

			if (this.options.checkVisibility
				&& !field.canBeSeenBy(this.unitScope.fPackage))
				continue next;

			char[] completionName = CharOperation.concat(field.name, SEMICOLON);

			int relevance = computeBaseRelevance();
			relevance += computeRelevanceForResolution();
			relevance += computeRelevanceForInterestingProposal();
			relevance += computeRelevanceForCaseMatching(fieldName, field.name);
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);

			this.noProposal = false;
			if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
				InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
				proposal.setDeclarationSignature(getSignature(field.declaringClass));
				proposal.setSignature(getSignature(field.type));
				proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
				proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
				proposal.setPackageName(field.type.qualifiedPackageName());
				proposal.setTypeName(field.type.qualifiedSourceName());
				proposal.setName(field.name);
				proposal.setCompletion(completionName);
				proposal.setFlags(field.modifiers);
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
				proposal.setRelevance(relevance);
				this.requestor.accept(proposal);
				if(DEBUG) {
					this.printDebug(proposal);
				}
			}
		}
	}

	private void findImportsOfStaticMethods(char[] methodName, ReferenceBinding ref) {
		MethodBinding[] methods = ref.availableMethods();

		int methodLength = methodName.length;
		next : for (int m = methods.length; --m >= 0;) {
			MethodBinding method = methods[m];

			if (method.isSynthetic()) continue next;

			if (method.isDefaultAbstract())	continue next;

			if (method.isConstructor()) continue next;

			if (!method.isStatic()) continue next;

			if (this.options.checkDeprecation && method.isViewedAsDeprecated()) continue next;

			if (this.options.checkVisibility
				&& !method.canBeSeenBy(this.unitScope.fPackage)) continue next;

			if (methodLength > method.selector.length)
				continue next;

			if (!CharOperation.prefixEquals(methodName, method.selector, false/* ignore case */)
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector)))
				continue next;

			int length = method.parameters.length;
			char[][] parameterPackageNames = new char[length][];
			char[][] parameterTypeNames = new char[length][];

			for (int i = 0; i < length; i++) {
				TypeBinding type = method.original().parameters[i];
				parameterPackageNames[i] = type.qualifiedPackageName();
				parameterTypeNames[i] = type.qualifiedSourceName();
			}
			char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);

			char[] completionName = CharOperation.concat(method.selector, SEMICOLON);

			int relevance = computeBaseRelevance();
			relevance += computeRelevanceForResolution();
			relevance += computeRelevanceForInterestingProposal();
			relevance += computeRelevanceForCaseMatching(methodName, method.selector);
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);

			this.noProposal = false;
			if(!this.requestor.isIgnored(CompletionProposal.METHOD_NAME_REFERENCE)) {
				InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_NAME_REFERENCE, this.actualCompletionPosition);
				proposal.setDeclarationSignature(getSignature(method.declaringClass));
				proposal.setSignature(getSignature(method));
				proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
				proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
				proposal.setParameterPackageNames(parameterPackageNames);
				proposal.setParameterTypeNames(parameterTypeNames);
				proposal.setPackageName(method.returnType.qualifiedPackageName());
				proposal.setTypeName(method.returnType.qualifiedSourceName());
				proposal.setName(method.selector);
				proposal.setCompletion(completionName);
				proposal.setFlags(method.modifiers);
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
				proposal.setRelevance(relevance);
				if(parameterNames != null) proposal.setParameterNames(parameterNames);
				this.requestor.accept(proposal);
				if(DEBUG) {
					this.printDebug(proposal);
				}
			}
		}
	}
	
	private void findInterfacesMethodDeclarations(
		char[] selector,
		ReferenceBinding receiverType,
		ReferenceBinding[] itsInterfaces,
		Scope scope,
		ObjectVector methodsFound,
		Binding[] missingElements,
		int[] missingElementssStarts,
		int[] missingElementsEnds,
		boolean missingElementsHaveProblems) {

		if (selector == null)
			return;

		if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
			ReferenceBinding[] interfacesToVisit = itsInterfaces;
			int nextPosition = interfacesToVisit.length;

			for (int i = 0; i < nextPosition; i++) {
				ReferenceBinding currentType = interfacesToVisit[i];
				MethodBinding[] methods = currentType.availableMethods();
				if(methods != null) {
					findLocalMethodDeclarations(
						selector,
						methods,
						scope,
						methodsFound,
						false,
						receiverType);
				}

				itsInterfaces = currentType.superInterfaces();
				if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
					int itsLength = itsInterfaces.length;
					if (nextPosition + itsLength >= interfacesToVisit.length)
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
					nextInterface : for (int a = 0; a < itsLength; a++) {
						ReferenceBinding next = itsInterfaces[a];
						for (int b = 0; b < nextPosition; b++)
							if (next == interfacesToVisit[b]) continue nextInterface;
						interfacesToVisit[nextPosition++] = next;
					}
				}
			}
		}
	}
	
	private void findInterfacesMethods(
		char[] selector,
		TypeBinding[] typeArgTypes,
		TypeBinding[] argTypes,
		ReferenceBinding receiverType,
		ReferenceBinding[] itsInterfaces,
		Scope scope,
		ObjectVector methodsFound,
		boolean onlyStaticMethods,
		boolean exactMatch,
		InvocationSite invocationSite,
		Scope invocationScope,
		boolean implicitCall,
		boolean superCall,
		boolean canBePrefixed,
		Binding[] missingElements,
		int[] missingElementssStarts,
		int[] missingElementsEnds,
		boolean missingElementsHaveProblems,
		char[] castedReceiver,
		int receiverStart,
		int receiverEnd) {

		if (selector == null)
			return;

		if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
			ReferenceBinding[] interfacesToVisit = itsInterfaces;
			int nextPosition = interfacesToVisit.length;

			for (int i = 0; i < nextPosition; i++) {
				ReferenceBinding currentType = interfacesToVisit[i];
				MethodBinding[] methods = currentType.availableMethods();
				if(methods != null) {
					findLocalMethods(
						selector,
						typeArgTypes,
						argTypes,
						methods,
						scope,
						methodsFound,
						onlyStaticMethods,
						exactMatch,
						receiverType,
						invocationSite,
						invocationScope,
						implicitCall,
						superCall,
						canBePrefixed,
						missingElements,
						missingElementssStarts,
						missingElementsEnds,
						missingElementsHaveProblems,
						castedReceiver,
						receiverStart,
						receiverEnd);
				}

				itsInterfaces = currentType.superInterfaces();
				if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
					int itsLength = itsInterfaces.length;
					if (nextPosition + itsLength >= interfacesToVisit.length)
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
					nextInterface : for (int a = 0; a < itsLength; a++) {
						ReferenceBinding next = itsInterfaces[a];
						for (int b = 0; b < nextPosition; b++)
							if (next == interfacesToVisit[b]) continue nextInterface;
						interfacesToVisit[nextPosition++] = next;
					}
				}
			}
		}
	}
	/*
	 * Find javadoc block tags for a given completion javadoc tag node
	 */
	private void findJavadocBlockTags(CompletionOnJavadocTag javadocTag) {
		char[][] possibleTags = javadocTag.getPossibleBlockTags();
		if (possibleTags == null) return;
		int length = possibleTags.length;
		for (int i=0; i<length; i++) {
			int relevance = computeBaseRelevance();
			relevance += computeRelevanceForInterestingProposal();
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywors

			this.noProposal = false;
			if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_BLOCK_TAG)) {
				char[] possibleTag = possibleTags[i];
				InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_BLOCK_TAG, this.actualCompletionPosition);
				proposal.setName(possibleTag);
				int tagLength = possibleTag.length;
				char[] completion = new char[1+tagLength];
				completion[0] = '@';
				System.arraycopy(possibleTag, 0, completion, 1, tagLength);
				proposal.setCompletion(completion);
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
				proposal.setRelevance(relevance);
				this.requestor.accept(proposal);
				if (DEBUG) {
					this.printDebug(proposal);
				}
			}
		}
	}

	/*
	 * Find javadoc inline tags for a given completion javadoc tag node
	 */
	private void findJavadocInlineTags(CompletionOnJavadocTag javadocTag) {
		char[][] possibleTags = javadocTag.getPossibleInlineTags();
		if (possibleTags == null) return;
		int length = possibleTags.length;
		for (int i=0; i<length; i++) {
			int relevance = computeBaseRelevance();
			relevance += computeRelevanceForInterestingProposal();
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywors

			this.noProposal = false;
			if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_INLINE_TAG)) {
				char[] possibleTag = possibleTags[i];
				InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_INLINE_TAG, this.actualCompletionPosition);
				proposal.setName(possibleTag);
				int tagLength = possibleTag.length;
//				boolean inlineTagStarted = javadocTag.completeInlineTagStarted();
				char[] completion = new char[2+tagLength+1];
				completion[0] = '{';
				completion[1] = '@';
				System.arraycopy(possibleTag, 0, completion, 2, tagLength);
				// do not add space at end of inline tag (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=121026)
				//completion[tagLength+2] = ' ';
				completion[tagLength+2] = '}';
				proposal.setCompletion(completion);
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
				proposal.setRelevance(relevance);
				this.requestor.accept(proposal);
				if (DEBUG) {
					this.printDebug(proposal);
				}
			}
		}
	}

	/*
	 * Find javadoc parameter names.
	 */
	private void findJavadocParamNames(char[] token, char[][] missingParams, boolean isTypeParam) {

		if (missingParams == null) return;

		// Get relevance
		int relevance = computeBaseRelevance();
		relevance += computeRelevanceForInterestingProposal();
		relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for param name
		if (!isTypeParam) relevance += R_INTERESTING;

		// Propose missing param
		int length = missingParams.length;
		relevance += length;
		for (int i=0; i<length; i++) {
			char[] argName = missingParams[i];
			if (token == null || CharOperation.prefixEquals(token, argName)) {

				this.noProposal = false;
				if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_PARAM_REF)) {
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_PARAM_REF, this.actualCompletionPosition);
					proposal.setName(argName);
					char[] completion = isTypeParam ? CharOperation.concat('<', argName, '>') : argName;
					proposal.setCompletion(completion);
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
					proposal.setRelevance(--relevance);
					this.requestor.accept(proposal);
					if (DEBUG) {
						this.printDebug(proposal);
					}
				}
			}
		}
	}

	// what about onDemand types? Ignore them since it does not happen!
	// import p1.p2.A.*;
	private void findKeywords(char[] keyword, char[][] choices, boolean canCompleteEmptyToken, boolean staticFieldsAndMethodOnly) {
		if(choices == null || choices.length == 0) return;

		int length = keyword.length;
		if (canCompleteEmptyToken || length > 0)
			for (int i = 0; i < choices.length; i++)
				if (length <= choices[i].length
					&& CharOperation.prefixEquals(keyword, choices[i], false /* ignore case */
				)){
					int relevance = computeBaseRelevance();
					relevance += computeRelevanceForResolution();
					relevance += computeRelevanceForInterestingProposal();
					relevance += computeRelevanceForCaseMatching(keyword, choices[i]);
					relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywords
					if (staticFieldsAndMethodOnly && this.insideQualifiedReference) relevance += R_NON_INHERITED;

					if(CharOperation.equals(choices[i], Keywords.TRUE) || CharOperation.equals(choices[i], Keywords.FALSE)) {
						relevance += computeRelevanceForExpectingType(TypeBinding.BOOLEAN);
						relevance += computeRelevanceForQualification(false);
					}
					this.noProposal = false;
					if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
						proposal.setName(choices[i]);
						proposal.setCompletion(choices[i]);
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
						proposal.setRelevance(relevance);
						this.requestor.accept(proposal);
						if(DEBUG) {
							this.printDebug(proposal);
						}
					}
				}
	}
	private void findKeywordsForMember(char[] token, int modifiers) {
		char[][] keywords = new char[Keywords.COUNT][];
		int count = 0;

		// visibility
		if((modifiers & ClassFileConstants.AccPrivate) == 0
			&& (modifiers & ClassFileConstants.AccProtected) == 0
			&& (modifiers & ClassFileConstants.AccPublic) == 0) {
			keywords[count++] = Keywords.PROTECTED;
			keywords[count++] = Keywords.PUBLIC;
			if((modifiers & ClassFileConstants.AccAbstract) == 0) {
				keywords[count++] = Keywords.PRIVATE;
			}
		}

		if((modifiers & ClassFileConstants.AccAbstract) == 0) {
			// abtract
			if((modifiers & ~(ExtraCompilerModifiers.AccVisibilityMASK | ClassFileConstants.AccStatic)) == 0) {
				keywords[count++] = Keywords.ABSTRACT;
			}

			// final
			if((modifiers & ClassFileConstants.AccFinal) == 0) {
				keywords[count++] = Keywords.FINAL;
			}

			// static
			if((modifiers & ClassFileConstants.AccStatic) == 0) {
				keywords[count++] = Keywords.STATIC;
			}

			boolean canBeField = true;
			boolean canBeMethod = true;
			boolean canBeType = true;
			if((modifiers & ClassFileConstants.AccNative) != 0
				|| (modifiers & ClassFileConstants.AccStrictfp) != 0
				|| (modifiers & ClassFileConstants.AccSynchronized) != 0) {
				canBeField = false;
				canBeType = false;
			}

			if((modifiers & ClassFileConstants.AccTransient) != 0
				|| (modifiers & ClassFileConstants.AccVolatile) != 0) {
				canBeMethod = false;
				canBeType = false;
			}

			if(canBeField) {
				// transient
				if((modifiers & ClassFileConstants.AccTransient) == 0) {
					keywords[count++] = Keywords.TRANSIENT;
				}

				// volatile
				if((modifiers & ClassFileConstants.AccVolatile) == 0) {
					keywords[count++] = Keywords.VOLATILE;
				}
			}

			if(canBeMethod) {
				// native
				if((modifiers & ClassFileConstants.AccNative) == 0) {
					keywords[count++] = Keywords.NATIVE;
				}

				// strictfp
				if((modifiers & ClassFileConstants.AccStrictfp) == 0) {
					keywords[count++] = Keywords.STRICTFP;
				}

				// synchronized
				if((modifiers & ClassFileConstants.AccSynchronized) == 0) {
					keywords[count++] = Keywords.SYNCHRONIZED;
				}
			}

			if(canBeType) {
				keywords[count++] = Keywords.CLASS;
				keywords[count++] = Keywords.INTERFACE;

				if((modifiers & ClassFileConstants.AccFinal) == 0) {
					keywords[count++] = Keywords.ENUM;
				}
			}
		} else {
			// class
			keywords[count++] = Keywords.CLASS;
			keywords[count++] = Keywords.INTERFACE;
		}
		System.arraycopy(keywords, 0, keywords = new char[count][], 0, count);

		findKeywords(token, keywords, false, false);
	}
	private void findLabels(char[] label, char[][] choices) {
		if(choices == null || choices.length == 0) return;

		int length = label.length;
		for (int i = 0; i < choices.length; i++) {
			if (length <= choices[i].length
				&& CharOperation.prefixEquals(label, choices[i], false /* ignore case */
			)){
				int relevance = computeBaseRelevance();
				relevance += computeRelevanceForResolution();
				relevance += computeRelevanceForInterestingProposal();
				relevance += computeRelevanceForCaseMatching(label, choices[i]);
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywors

				this.noProposal = false;
				if(!this.requestor.isIgnored(CompletionProposal.LABEL_REF)) {
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.LABEL_REF, this.actualCompletionPosition);
					proposal.setName(choices[i]);
					proposal.setCompletion(choices[i]);
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
					proposal.setRelevance(relevance);
					this.requestor.accept(proposal);
					if(DEBUG) {
						this.printDebug(proposal);
					}
				}
			}
		}
	}

	// Helper method for findMethods(char[], MethodBinding[], Scope, ObjectVector, boolean, boolean, boolean, TypeBinding)
	private void findLocalMethodDeclarations(
		char[] methodName,
		MethodBinding[] methods,
		Scope scope,
		ObjectVector methodsFound,
		//	boolean noVoidReturnType, how do you know?
		boolean exactMatch,
		ReferenceBinding receiverType) {

		ObjectVector newMethodsFound =  new ObjectVector();
		// Inherited methods which are hidden by subclasses are filtered out
		// No visibility checks can be performed without the scope & invocationSite
		int methodLength = methodName.length;
		next : for (int f = methods.length; --f >= 0;) {

			MethodBinding method = methods[f];
			if (method.isSynthetic())	continue next;

			if (method.isDefaultAbstract()) continue next;

			if (method.isConstructor()) continue next;

			if (method.isFinal()) {
                newMethodsFound.add(method);
                continue next;
            }

			if (this.options.checkDeprecation &&
					method.isViewedAsDeprecated() &&
					!scope.isDefinedInSameUnit(method.declaringClass))
				continue next;

			//		if (noVoidReturnType && method.returnType == BaseTypes.VoidBinding) continue next;
			if(method.isStatic()) continue next;

			if (!method.canBeSeenBy(receiverType, FakeInvocationSite , scope)) continue next;

			if (exactMatch) {
				if (!CharOperation.equals(methodName, method.selector, false /* ignore case */
					))
					continue next;

			} else {

				if (methodLength > method.selector.length)
					continue next;

				if (!CharOperation.prefixEquals(methodName, method.selector, false/* ignore case */)
						&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector)))
					continue next;
			}

			for (int i = methodsFound.size; --i >= 0;) {
				MethodBinding otherMethod = (MethodBinding) methodsFound.elementAt(i);
				if (method == otherMethod)
					continue next;

				if (CharOperation.equals(method.selector, otherMethod.selector, true)
						&& this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
					continue next;
				}
			}

			newMethodsFound.add(method);

			int length = method.parameters.length;
			char[][] parameterPackageNames = new char[length][];
			char[][] parameterFullTypeNames = new char[length][];

			for (int i = 0; i < length; i++) {
				TypeBinding type = method.parameters[i];
				parameterPackageNames[i] = type.qualifiedPackageName();
				parameterFullTypeNames[i] = type.qualifiedSourceName();
			}

			char[][] parameterNames = findMethodParameterNames(method, parameterFullTypeNames);

			if(method.typeVariables != null && method.typeVariables.length > 0) {
				char[][] excludedNames = findEnclosingTypeNames(scope);
				char[][] substituedParameterNames = substituteMethodTypeParameterNames(method.typeVariables, excludedNames);
				if(substituedParameterNames != null) {
					method = new ParameterizedMethodBinding(
								method.declaringClass,
								method,
								substituedParameterNames,
								scope.environment());
				}
			}

			StringBuffer completion = new StringBuffer(10);
			if (!exactMatch) {
				createMethod(method, parameterPackageNames, parameterFullTypeNames, parameterNames, scope, completion);
			}

			int relevance = computeBaseRelevance();
			relevance += computeRelevanceForResolution();
			relevance += computeRelevanceForInterestingProposal();
			relevance += computeRelevanceForCaseMatching(methodName, method.selector);
			relevance += R_METHOD_OVERIDE;
			if(method.isAbstract()) relevance += R_ABSTRACT_METHOD;
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);

			this.noProposal = false;
			if(!this.requestor.isIgnored(CompletionProposal.METHOD_DECLARATION)) {
				InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_DECLARATION, this.actualCompletionPosition);
				proposal.setDeclarationSignature(getSignature(method.declaringClass));
				proposal.setDeclarationKey(method.declaringClass.computeUniqueKey());
				proposal.setSignature(getSignature(method));
				MethodBinding original = method.original();
				if(original != method) {
					proposal.setOriginalSignature(getSignature(original));
				}
				proposal.setKey(method.computeUniqueKey());
				proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
				proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
				proposal.setParameterPackageNames(parameterPackageNames);
				proposal.setParameterTypeNames(parameterFullTypeNames);
				proposal.setPackageName(method.returnType.qualifiedPackageName());
				proposal.setTypeName(method.returnType.qualifiedSourceName());
				proposal.setCompletion(completion.toString().toCharArray());
				proposal.setName(method.selector);
				proposal.setFlags(method.modifiers);
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
				proposal.setRelevance(relevance);
				if(parameterNames != null) proposal.setParameterNames(parameterNames);
				this.requestor.accept(proposal);
				if(DEBUG) {
					this.printDebug(proposal);
				}
			}
		}
		methodsFound.addAll(newMethodsFound);
	}

	// Helper method for findMethods(char[], TypeBinding[], ReferenceBinding, Scope, ObjectVector, boolean, boolean, boolean)
	private void findLocalMethods(
		char[] methodName,
		TypeBinding[] typeArgTypes,
		TypeBinding[] argTypes,
		MethodBinding[] methods,
		Scope scope,
		ObjectVector methodsFound,
		boolean onlyStaticMethods,
		boolean exactMatch,
		ReferenceBinding receiverType,
		InvocationSite invocationSite,
		Scope invocationScope,
		boolean implicitCall,
		boolean superCall,
		boolean canBePrefixed,
		Binding[] missingElements,
		int[] missingElementsStarts,
		int[] missingElementsEnds,
		boolean missingElementsHaveProblems,
		char[] castedReceiver,
		int receiverStart,
		int receiverEnd) {

		ObjectVector newMethodsFound =  new ObjectVector();
		// Inherited methods which are hidden by subclasses are filtered out
		// No visibility checks can be performed without the scope & invocationSite

		int methodLength = methodName.length;
		int minTypeArgLength = typeArgTypes == null ? 0 : typeArgTypes.length;
		int minArgLength = argTypes == null ? 0 : argTypes.length;

		next : for (int f = methods.length; --f >= 0;) {
			MethodBinding method = methods[f];

			if (method.isSynthetic()) continue next;

			if (method.isDefaultAbstract())	continue next;

			if (method.isConstructor()) continue next;

			if (this.options.checkDeprecation &&
					method.isViewedAsDeprecated() &&
					!scope.isDefinedInSameUnit(method.declaringClass))
				continue next;

			//TODO (david) perhaps the relevance of a void method must be lesser than other methods
			//if (expectedTypesPtr > -1 && method.returnType == BaseTypes.VoidBinding) continue next;

			if (onlyStaticMethods && !method.isStatic()) continue next;

			if (this.options.checkVisibility
				&& !method.canBeSeenBy(receiverType, invocationSite, scope)) continue next;

			if(superCall && method.isAbstract()) {
				methodsFound.add(new Object[]{method, receiverType});
				continue next;
			}

			if (exactMatch) {
				if (!CharOperation.equals(methodName, method.selector, false /* ignore case */)) {
					continue next;
				}
			} else {
				if (methodLength > method.selector.length) continue next;
				if (!CharOperation.prefixEquals(methodName, method.selector, false /* ignore case */)
						&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector))) {
					continue next;
				}
			}

			if (minTypeArgLength != 0 && minTypeArgLength != method.typeVariables.length)
				continue next;

			if (minTypeArgLength != 0) {
				method = scope.environment().createParameterizedGenericMethod(method, typeArgTypes);
			}

			if (minArgLength > method.parameters.length)
				continue next;

			for (int a = minArgLength; --a >= 0;){
				if (argTypes[a] != null) { // can be null if it could not be resolved properly
					if (!argTypes[a].isCompatibleWith(method.parameters[a])) {
						continue next;
					}
				}
			}

			boolean prefixRequired = false;

			for (int i = methodsFound.size; --i >= 0;) {
				Object[] other = (Object[]) methodsFound.elementAt(i);
				MethodBinding otherMethod = (MethodBinding) other[0];
				ReferenceBinding otherReceiverType = (ReferenceBinding) other[1];
				if (method == otherMethod && receiverType == otherReceiverType)
					continue next;

				if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
					if (receiverType == otherReceiverType) {
						if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
							if (!superCall || !otherMethod.declaringClass.isInterface()) {
								continue next;
							}
						}
					} else {
						if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
							if(receiverType.isAnonymousType()) continue next;

							if(!superCall) {
								if(!canBePrefixed) continue next;

								prefixRequired = true;
							}
						}
					}
				}
			}

			newMethodsFound.add(new Object[]{method, receiverType});

			ReferenceBinding superTypeWithSameErasure = (ReferenceBinding)receiverType.findSuperTypeOriginatingFrom(method.declaringClass);
			if (method.declaringClass != superTypeWithSameErasure) {
				MethodBinding[] otherMethods = superTypeWithSameErasure.getMethods(method.selector);
				for (int i = 0; i < otherMethods.length; i++) {
					if(otherMethods[i].original() == method.original()) {
						method = otherMethods[i];
					}
				}
			}

			int length = method.parameters.length;
			char[][] parameterPackageNames = new char[length][];
			char[][] parameterTypeNames = new char[length][];

			for (int i = 0; i < length; i++) {
				TypeBinding type = method.original().parameters[i];
				parameterPackageNames[i] = type.qualifiedPackageName();
				parameterTypeNames[i] = type.qualifiedSourceName();
			}
			char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);

			char[] completion = CharOperation.NO_CHAR;

			int previousStartPosition = this.startPosition;
			int previousTokenStart = this.tokenStart;

			// Special case for completion in javadoc
			if (this.assistNodeInJavadoc > 0) {
				Expression receiver = null;
				if (invocationSite instanceof CompletionOnJavadocMessageSend) {
					CompletionOnJavadocMessageSend msg = (CompletionOnJavadocMessageSend) invocationSite;
					receiver = msg.receiver;
				} else if (invocationSite instanceof CompletionOnJavadocFieldReference) {
					CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) invocationSite;
					receiver = fieldRef.receiver;
				}
				if (receiver != null) {
					StringBuffer javadocCompletion = new StringBuffer();
					if (receiver.isThis()) {
						if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
							javadocCompletion.append('#');
						}
					} else if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
						if (receiver instanceof JavadocSingleTypeReference) {
							JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) receiver;
							javadocCompletion.append(typeRef.token);
							javadocCompletion.append('#');
						} else if (receiver instanceof JavadocQualifiedTypeReference) {
							JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) receiver;
							completion = CharOperation.concat(CharOperation.concatWith(typeRef.tokens, '.'), method.selector, '#');
							for (int t=0,nt =typeRef.tokens.length; t<nt; t++) {
								if (t>0) javadocCompletion.append('.');
								javadocCompletion.append(typeRef.tokens[t]);
							}
							javadocCompletion.append('#');
						}
					}
					javadocCompletion.append(method.selector);
					// Append parameters types
					javadocCompletion.append('(');
					if (method.parameters != null) {
						boolean isVarargs = method.isVarargs();
						for (int p=0, ln=method.parameters.length; p<ln; p++) {
							if (p>0) javadocCompletion.append(", "); //$NON-NLS-1$
							TypeBinding argTypeBinding = method.parameters[p];
							if (isVarargs && p == ln - 1)  {
								createVargsType(argTypeBinding.erasure(), scope, javadocCompletion);
							} else {
								createType(argTypeBinding.erasure(), scope,javadocCompletion);
							}
						}
					}
					javadocCompletion.append(')');
					completion = javadocCompletion.toString().toCharArray();
				}
			} else {
				// nothing to insert - do not want to replace the existing selector & arguments
				if (!exactMatch) {
					if (this.source != null
						&& this.source.length > this.endPosition
						&& this.source[this.endPosition] == '(')
						completion = method.selector;
					else
						completion = CharOperation.concat(method.selector, new char[] { '(', ')' });

					if (castedReceiver != null) {
						completion = CharOperation.concat(castedReceiver, completion);
					}
				} else {
					if(prefixRequired && (this.source != null)) {
						completion = CharOperation.subarray(this.source, this.startPosition, this.endPosition);
					} else {
						this.startPosition = this.endPosition;
					}
					this.tokenStart = this.tokenEnd;
				}

				if(prefixRequired || this.options.forceImplicitQualification){
					char[] prefix = computePrefix(scope.enclosingSourceType(), invocationScope.enclosingSourceType(), method.isStatic());
					completion = CharOperation.concat(prefix,completion,'.');
				}
			}

			int relevance = computeBaseRelevance();
			relevance += computeRelevanceForResolution();
			relevance += computeRelevanceForInterestingProposal();
			relevance += computeRelevanceForCaseMatching(methodName, method.selector);
			relevance += computeRelevanceForExpectingType(method.returnType);
			relevance += computeRelevanceForEnumConstant(method.returnType);
			relevance += computeRelevanceForStatic(onlyStaticMethods, method.isStatic());
			relevance += computeRelevanceForQualification(prefixRequired);
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
			if (onlyStaticMethods && this.insideQualifiedReference) {
				relevance += computeRelevanceForInheritance(receiverType, method.declaringClass);
			}
			if (missingElements != null) {
				relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
			}

			this.noProposal = false;

			if (castedReceiver == null) {
				// Standard proposal
				if(!this.isIgnored(CompletionProposal.METHOD_REF, missingElements != null) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
					proposal.setDeclarationSignature(getSignature(method.declaringClass));
					proposal.setSignature(getSignature(method));
					MethodBinding original = method.original();
					if(original != method) {
						proposal.setOriginalSignature(getSignature(original));
					}
					proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
					proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
					proposal.setParameterPackageNames(parameterPackageNames);
					proposal.setParameterTypeNames(parameterTypeNames);
					proposal.setPackageName(method.returnType.qualifiedPackageName());
					proposal.setTypeName(method.returnType.qualifiedSourceName());
					proposal.setName(method.selector);
					if (missingElements != null) {
						CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
						for (int i = 0; i < missingElements.length; i++) {
							subProposals[i] =
								createRequiredTypeProposal(
										missingElements[i],
										missingElementsStarts[i],
										missingElementsEnds[i],
										relevance);
						}
						proposal.setRequiredProposals(subProposals);
					}
					proposal.setCompletion(completion);
					proposal.setFlags(method.modifiers);
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
					proposal.setRelevance(relevance);
					if(parameterNames != null) proposal.setParameterNames(parameterNames);
					this.requestor.accept(proposal);
					if(DEBUG) {
						this.printDebug(proposal);
					}
				}

				// Javadoc proposal
				if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_METHOD_REF)) {
					char[] javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_LINK);
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_METHOD_REF, this.actualCompletionPosition);
					proposal.setDeclarationSignature(getSignature(method.declaringClass));
					proposal.setSignature(getSignature(method));
					MethodBinding original = method.original();
					if(original != method) {
						proposal.setOriginalSignature(getSignature(original));
					}
					proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
					proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
					proposal.setParameterPackageNames(parameterPackageNames);
					proposal.setParameterTypeNames(parameterTypeNames);
					proposal.setPackageName(method.returnType.qualifiedPackageName());
					proposal.setTypeName(method.returnType.qualifiedSourceName());
					proposal.setName(method.selector);
					proposal.setCompletion(javadocCompletion);
					proposal.setFlags(method.modifiers);
					int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
					proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
					proposal.setRelevance(relevance+R_INLINE_TAG);
					if(parameterNames != null) proposal.setParameterNames(parameterNames);
					this.requestor.accept(proposal);
					if(DEBUG) {
						this.printDebug(proposal);
					}
				}
			} else {
				if(!this.isIgnored(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, missingElements != null)) {
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, this.actualCompletionPosition);
					proposal.setDeclarationSignature(getSignature(method.declaringClass));
					proposal.setSignature(getSignature(method));
					MethodBinding original = method.original();
					if(original != method) {
						proposal.setOriginalSignature(getSignature(original));
					}
					proposal.setReceiverSignature(getSignature(receiverType));
					proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
					proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
					proposal.setParameterPackageNames(parameterPackageNames);
					proposal.setParameterTypeNames(parameterTypeNames);
					proposal.setPackageName(method.returnType.qualifiedPackageName());
					proposal.setTypeName(method.returnType.qualifiedSourceName());
					proposal.setName(method.selector);
					if (missingElements != null) {
						CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
						for (int i = 0; i < missingElements.length; i++) {
							subProposals[i] =
								createRequiredTypeProposal(
										missingElements[i],
										missingElementsStarts[i],
										missingElementsEnds[i],
										relevance);
						}
						proposal.setRequiredProposals(subProposals);
					}
					proposal.setCompletion(completion);
					proposal.setFlags(method.modifiers);
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
					proposal.setReceiverRange(receiverStart - this.offset, receiverEnd - this.offset);
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
					proposal.setRelevance(relevance);
					if(parameterNames != null) proposal.setParameterNames(parameterNames);
					this.requestor.accept(proposal);
					if(DEBUG) {
						this.printDebug(proposal);
					}
				}
			}
			this.startPosition = previousStartPosition;
			this.tokenStart = previousTokenStart;
		}

		methodsFound.addAll(newMethodsFound);
	}
	private void findLocalMethodsFromFavorites(
			char[] methodName,
			MethodBinding[] methods,
			Scope scope,
			ObjectVector methodsFound,
			ObjectVector methodsFoundFromFavorites,
			ReferenceBinding receiverType,
			InvocationSite invocationSite,
			Scope invocationScope) {

			char[] typeName = CharOperation.concatWith(receiverType.compoundName, '.');

			int methodLength = methodName.length;

			next : for (int f = methods.length; --f >= 0;) {
				MethodBinding method = methods[f];

				if (method.isSynthetic()) continue next;

				if (method.isDefaultAbstract())	continue next;

				if (method.isConstructor()) continue next;

				if (this.options.checkDeprecation &&
						method.isViewedAsDeprecated() &&
						!scope.isDefinedInSameUnit(method.declaringClass))
					continue next;

				if (!method.isStatic()) continue next;

				if (this.options.checkVisibility
					&& !method.canBeSeenBy(receiverType, invocationSite, scope)) continue next;

				if (methodLength > method.selector.length) continue next;

				if (!CharOperation.prefixEquals(methodName, method.selector, false /* ignore case */)
						&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector))) {
					continue next;
				}

				for (int i = methodsFoundFromFavorites.size; --i >= 0;) {
					Object[] other = (Object[]) methodsFoundFromFavorites.elementAt(i);
					MethodBinding otherMethod = (MethodBinding) other[0];

					if (method == otherMethod) continue next;

					if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
						if (otherMethod.declaringClass == method.declaringClass &&
								this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
							continue next;
						}
					}
				}

				for (int i = methodsFound.size; --i >= 0;) {
					Object[] other = (Object[]) methodsFound.elementAt(i);
					MethodBinding otherMethod = (MethodBinding) other[0];

					if (method == otherMethod) continue next;

					if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
						if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
							continue next;
						}
					}
				}

				boolean proposeStaticImport = !(this.compilerOptions.complianceLevel < ClassFileConstants.JDK1_5) &&
					this.options.suggestStaticImport;

				boolean isAlreadyImported = false;
				if (!proposeStaticImport) {
					if(!this.importCachesInitialized) {
						initializeImportCaches();
					}
					for (int j = 0; j < this.importCacheCount; j++) {
						char[][] importName = this.importsCache[j];
						if(CharOperation.equals(receiverType.sourceName, importName[0])) {
							if (!CharOperation.equals(typeName, importName[1])) {
								continue next;
							} else {
								isAlreadyImported = true;
							}
						}
					}
				}

				methodsFoundFromFavorites.add(new Object[]{method, receiverType});

				ReferenceBinding superTypeWithSameErasure = (ReferenceBinding)receiverType.findSuperTypeOriginatingFrom(method.declaringClass);
				if (method.declaringClass != superTypeWithSameErasure) {
					MethodBinding[] otherMethods = superTypeWithSameErasure.getMethods(method.selector);
					for (int i = 0; i < otherMethods.length; i++) {
						if(otherMethods[i].original() == method.original()) {
							method = otherMethods[i];
						}
					}
				}

				int length = method.parameters.length;
				char[][] parameterPackageNames = new char[length][];
				char[][] parameterTypeNames = new char[length][];

				for (int i = 0; i < length; i++) {
					TypeBinding type = method.original().parameters[i];
					parameterPackageNames[i] = type.qualifiedPackageName();
					parameterTypeNames[i] = type.qualifiedSourceName();
				}
				char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);

				char[] completion = CharOperation.NO_CHAR;

				int previousStartPosition = this.startPosition;
				int previousTokenStart = this.tokenStart;

				if (this.source != null
					&& this.source.length > this.endPosition
					&& this.source[this.endPosition] == '(') {
					completion = method.selector;
				} else {
					completion = CharOperation.concat(method.selector, new char[] { '(', ')' });
				}

				int relevance = computeBaseRelevance();
				relevance += computeRelevanceForResolution();
				relevance += computeRelevanceForInterestingProposal();
				relevance += computeRelevanceForCaseMatching(methodName, method.selector);
				relevance += computeRelevanceForExpectingType(method.returnType);
				relevance += computeRelevanceForEnumConstant(method.returnType);
				relevance += computeRelevanceForStatic(true, method.isStatic());
				relevance += computeRelevanceForQualification(true);
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);

				CompilationUnitDeclaration cu = this.unitScope.referenceContext;
				int importStart = cu.types[0].declarationSourceStart;
				int importEnd = importStart;

				this.noProposal = false;

				if (!proposeStaticImport) {
					if (isAlreadyImported) {
						if (!isIgnored(CompletionProposal.METHOD_REF)) {
							completion = CharOperation.concat(receiverType.sourceName, completion, '.');

							InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
							proposal.setDeclarationSignature(getSignature(method.declaringClass));
							proposal.setSignature(getSignature(method));
							MethodBinding original = method.original();
							if(original != method) {
								proposal.setOriginalSignature(getSignature(original));
							}
							proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
							proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
							proposal.setParameterPackageNames(parameterPackageNames);
							proposal.setParameterTypeNames(parameterTypeNames);
							proposal.setPackageName(method.returnType.qualifiedPackageName());
							proposal.setTypeName(method.returnType.qualifiedSourceName());
							proposal.setName(method.selector);
							proposal.setCompletion(completion);
							proposal.setFlags(method.modifiers);
							proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
							proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
							proposal.setRelevance(relevance);
							if(parameterNames != null) proposal.setParameterNames(parameterNames);

							this.requestor.accept(proposal);
							if(DEBUG) {
								this.printDebug(proposal);
							}
						}
					} else if (!this.isIgnored(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_IMPORT)) {
						completion = CharOperation.concat(receiverType.sourceName, completion, '.');

						InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
						proposal.setDeclarationSignature(getSignature(method.declaringClass));
						proposal.setSignature(getSignature(method));
						MethodBinding original = method.original();
						if(original != method) {
							proposal.setOriginalSignature(getSignature(original));
						}
						proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
						proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
						proposal.setParameterPackageNames(parameterPackageNames);
						proposal.setParameterTypeNames(parameterTypeNames);
						proposal.setPackageName(method.returnType.qualifiedPackageName());
						proposal.setTypeName(method.returnType.qualifiedSourceName());
						proposal.setName(method.selector);
						proposal.setCompletion(completion);
						proposal.setFlags(method.modifiers);
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
						proposal.setRelevance(relevance);
						if(parameterNames != null) proposal.setParameterNames(parameterNames);

						char[] typeImportCompletion = createImportCharArray(typeName, false, false);

						InternalCompletionProposal typeImportProposal = createProposal(CompletionProposal.TYPE_IMPORT, this.actualCompletionPosition);
						typeImportProposal.nameLookup = this.nameEnvironment.nameLookup;
						typeImportProposal.completionEngine = this;
						char[] packageName = receiverType.qualifiedPackageName();
						typeImportProposal.setDeclarationSignature(packageName);
						typeImportProposal.setSignature(getSignature(receiverType));
						typeImportProposal.setPackageName(packageName);
						typeImportProposal.setTypeName(receiverType.qualifiedSourceName());
						typeImportProposal.setCompletion(typeImportCompletion);
						typeImportProposal.setFlags(receiverType.modifiers);
						typeImportProposal.setAdditionalFlags(CompletionFlags.Default);
						typeImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
						typeImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset);
						typeImportProposal.setRelevance(relevance);

						proposal.setRequiredProposals(new CompletionProposal[]{typeImportProposal});

						this.requestor.accept(proposal);
						if(DEBUG) {
							this.printDebug(proposal);
						}
					}
				} else {
					if (!this.isIgnored(CompletionProposal.METHOD_REF, CompletionProposal.METHOD_IMPORT)) {
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
						proposal.setDeclarationSignature(getSignature(method.declaringClass));
						proposal.setSignature(getSignature(method));
						MethodBinding original = method.original();
						if(original != method) {
							proposal.setOriginalSignature(getSignature(original));
						}
						proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
						proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
						proposal.setParameterPackageNames(parameterPackageNames);
						proposal.setParameterTypeNames(parameterTypeNames);
						proposal.setPackageName(method.returnType.qualifiedPackageName());
						proposal.setTypeName(method.returnType.qualifiedSourceName());
						proposal.setName(method.selector);
						proposal.setCompletion(completion);
						proposal.setFlags(method.modifiers);
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
						proposal.setRelevance(relevance);
						if(parameterNames != null) proposal.setParameterNames(parameterNames);

						char[] methodImportCompletion = createImportCharArray(CharOperation.concat(typeName, method.selector, '.'), true, false);

						InternalCompletionProposal methodImportProposal = createProposal(CompletionProposal.METHOD_IMPORT, this.actualCompletionPosition);
						methodImportProposal.setDeclarationSignature(getSignature(method.declaringClass));
						methodImportProposal.setSignature(getSignature(method));
						if(original != method) {
							proposal.setOriginalSignature(getSignature(original));
						}
						methodImportProposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
						methodImportProposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
						methodImportProposal.setParameterPackageNames(parameterPackageNames);
						methodImportProposal.setParameterTypeNames(parameterTypeNames);
						methodImportProposal.setPackageName(method.returnType.qualifiedPackageName());
						methodImportProposal.setTypeName(method.returnType.qualifiedSourceName());
						methodImportProposal.setName(method.selector);
						methodImportProposal.setCompletion(methodImportCompletion);
						methodImportProposal.setFlags(method.modifiers);
						methodImportProposal.setAdditionalFlags(CompletionFlags.StaticImport);
						methodImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
						methodImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset);
						methodImportProposal.setRelevance(relevance);
						if(parameterNames != null) methodImportProposal.setParameterNames(parameterNames);

						proposal.setRequiredProposals(new CompletionProposal[]{methodImportProposal});

						this.requestor.accept(proposal);
						if(DEBUG) {
							this.printDebug(proposal);
						}
					}
				}

				this.startPosition = previousStartPosition;
				this.tokenStart = previousTokenStart;
			}
		}

	/**
	 * Helper method for findMethods(char[], TypeBinding[], ReferenceBinding, Scope, ObjectVector, boolean, boolean, boolean)
	 * Note that the method doesn't do a comparison of the method names and expects the client to handle the same.
	 * 
	 * @methodName method as entered by the user, the one to completed
	 * @param methods a resultant array of MethodBinding, whose names should match methodName. The calling client must ensure that this check is handled.
	 */
	private void findLocalMethodsFromStaticImports(
		char[] methodName,
		MethodBinding[] methods,
		Scope scope,
		boolean exactMatch,
		ObjectVector methodsFound,
		ReferenceBinding receiverType,
		InvocationSite invocationSite) {

		ObjectVector newMethodsFound =  new ObjectVector();

		next : for (int f = methods.length; --f >= 0;) {
			MethodBinding method = methods[f];

			if (method.isSynthetic()) continue next;

			if (method.isDefaultAbstract())	continue next;

			if (method.isConstructor()) continue next;

			if (!method.isStatic()) continue next;

			if (this.options.checkDeprecation &&
					method.isViewedAsDeprecated() &&
					!scope.isDefinedInSameUnit(method.declaringClass))
				continue next;

			if (this.options.checkVisibility
				&& !method.canBeSeenBy(receiverType, invocationSite, scope)) continue next;

			for (int i = methodsFound.size; --i >= 0;) {
				Object[] other = (Object[]) methodsFound.elementAt(i);
				MethodBinding otherMethod = (MethodBinding) other[0];
				ReferenceBinding otherReceiverType = (ReferenceBinding) other[1];
				if (method == otherMethod && receiverType == otherReceiverType)
					continue next;

				if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
					if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
						continue next;
					}
				}
			}

			newMethodsFound.add(new Object[]{method, receiverType});

			int length = method.parameters.length;
			char[][] parameterPackageNames = new char[length][];
			char[][] parameterTypeNames = new char[length][];

			for (int i = 0; i < length; i++) {
				TypeBinding type = method.original().parameters[i];
				parameterPackageNames[i] = type.qualifiedPackageName();
				parameterTypeNames[i] = type.qualifiedSourceName();
			}
			char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);

			char[] completion = CharOperation.NO_CHAR;

			int previousStartPosition = this.startPosition;
			int previousTokenStart = this.tokenStart;

			if (!exactMatch) {
				if (this.source != null
					&& this.source.length > this.endPosition
					&& this.source[this.endPosition] == '(') {
					completion = method.selector;
				} else {
					completion = CharOperation.concat(method.selector, new char[] { '(', ')' });
				}
			} else {
				this.startPosition = this.endPosition;
				this.tokenStart = this.tokenEnd;
			}

			int relevance = computeBaseRelevance();
			relevance += computeRelevanceForResolution();
			relevance += computeRelevanceForInterestingProposal();
			relevance += computeRelevanceForCaseMatching(methodName, method.selector);
			relevance += computeRelevanceForExpectingType(method.returnType);
			relevance += computeRelevanceForEnumConstant(method.returnType);
			relevance += computeRelevanceForStatic(true, method.isStatic());
			relevance += computeRelevanceForQualification(false);
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);

			this.noProposal = false;
			if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
				InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
				proposal.setDeclarationSignature(getSignature(method.declaringClass));
				proposal.setSignature(getSignature(method));
				MethodBinding original = method.original();
				if(original != method) {
					proposal.setOriginalSignature(getSignature(original));
				}
				proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
				proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
				proposal.setParameterPackageNames(parameterPackageNames);
				proposal.setParameterTypeNames(parameterTypeNames);
				proposal.setPackageName(method.returnType.qualifiedPackageName());
				proposal.setTypeName(method.returnType.qualifiedSourceName());
				proposal.setName(method.selector);
				proposal.setCompletion(completion);
				proposal.setFlags(method.modifiers);
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
				proposal.setRelevance(relevance);
				if(parameterNames != null) proposal.setParameterNames(parameterNames);
				this.requestor.accept(proposal);
				if(DEBUG) {
					this.printDebug(proposal);
				}
			}
			this.startPosition = previousStartPosition;
			this.tokenStart = previousTokenStart;
		}

		methodsFound.addAll(newMethodsFound);
	}

	private void findLocalMethodsFromStaticImports(
			char[] token,
			Scope scope,
			InvocationSite invocationSite,
			Scope invocationScope,
			boolean exactMatch,
			ObjectVector methodsFound,
			boolean proposeMethod) {
		findFieldsAndMethodsFromStaticImports(
				token,
				scope,
				invocationSite,
				invocationScope,
				exactMatch,
				false,
				new ObjectVector(),
				new ObjectVector(),
				methodsFound,
				false,
				proposeMethod);
	}
	protected void findMembers(
			char[] token,
			ReferenceBinding receiverType,
			Scope scope,
			InvocationSite invocationSite,
			boolean isInsideAnnotationAttribute,
			Binding[] missingElements,
			int[] missingElementsStarts,
			int[] missingElementsEnds,
			boolean missingElementsHaveProblems) {

		if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
			findMemberTypes(
					token,
					receiverType,
					scope,
					scope.enclosingSourceType(),
					false,
					true,
					new ObjectVector(),
					missingElements,
					missingElementsStarts,
					missingElementsEnds,
					missingElementsHaveProblems);
		}
		if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
			findClassField(
					token,
					receiverType,
					scope,
					missingElements,
					missingElementsStarts,
					missingElementsEnds,
					missingElementsHaveProblems);
		}

		MethodScope methodScope = null;
		if (!isInsideAnnotationAttribute &&
				!this.requestor.isIgnored(CompletionProposal.KEYWORD) &&
				((scope instanceof MethodScope && !((MethodScope)scope).isStatic)
				|| ((methodScope = scope.enclosingMethodScope()) != null && !methodScope.isStatic))) {
			if (token.length > 0) {
				findKeywords(token, new char[][]{Keywords.THIS}, false, true);
			} else {
				int relevance = computeBaseRelevance();
				relevance += computeRelevanceForResolution();
				relevance += computeRelevanceForInterestingProposal();
				relevance += computeRelevanceForCaseMatching(this.completionToken, Keywords.THIS);
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywords
				relevance += R_NON_INHERITED;

				this.noProposal = false;
				if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
					proposal.setName(Keywords.THIS);
					proposal.setCompletion(Keywords.THIS);
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
					proposal.setRelevance(relevance);
					this.requestor.accept(proposal);
					if (DEBUG) {
						this.printDebug(proposal);
					}
				}
			}
		}

		if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
			findFields(
				token,
				receiverType,
				scope,
				new ObjectVector(),
				new ObjectVector(),
				true,
				invocationSite,
				scope,
				false,
				false,
				missingElements,
				missingElementsStarts,
				missingElementsEnds,
				missingElementsHaveProblems,
				null,
				-1,
				-1);
		}

		if (!isInsideAnnotationAttribute && !this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
			findMethods(
				token,
				null,
				null,
				receiverType,
				scope,
				new ObjectVector(),
				true,
				false,
				invocationSite,
				scope,
				false,
				false,
				false,
				missingElements,
				missingElementsStarts,
				missingElementsEnds,
				missingElementsHaveProblems,
				null,
				-1,
				-1);
		}
	}

	private void findMembersFromMissingType(
			final char[] token,
			final long pos,
			TypeBinding resolveType,
			final Scope scope,
			final InvocationSite invocationSite,
			final boolean isInsideAnnotationAttribute) {
		MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this);
		MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor =
			new MissingTypesGuesser.GuessedTypeRequestor() {
				public void accept(
						TypeBinding guessedType,
						Binding[] missingElements,
						int[] missingElementsStarts,
						int[] missingElementsEnds,
						boolean hasProblems) {
					if (guessedType instanceof ReferenceBinding) {
						findMembers(
								CompletionEngine.this.completionToken,
								(ReferenceBinding)guessedType,
								scope,
								invocationSite,
								isInsideAnnotationAttribute,
								missingElements,
								missingElementsStarts,
								missingElementsEnds,
								hasProblems);
					}
				}
			};
		SingleTypeReference typeRef = new SingleTypeReference(token, pos);
		typeRef.resolvedType = new ProblemReferenceBinding(new char[][]{ token }, null, ProblemReasons.NotFound);
		missingTypesConverter.guess(typeRef, scope, substitutionRequestor);
	}

	private void findMemberTypes(
		char[] typeName,
		ReferenceBinding receiverType,
		Scope scope,
		SourceTypeBinding typeInvocation,
		boolean staticOnly,
		boolean staticFieldsAndMethodOnly,
		boolean fromStaticImport,
		boolean checkQualification,
		boolean proposeAllMemberTypes,
		SourceTypeBinding typeToIgnore,
		ObjectVector typesFound,
		Binding[] missingElements,
		int[] missingElementsStarts,
		int[] missingElementsEnds,
		boolean missingElementsHaveProblems) {

		ReferenceBinding currentType = receiverType;
		if (typeName == null)
			return;

		if (this.insideQualifiedReference
			|| typeName.length == 0) { // do not search up the hierarchy

			findMemberTypes(
				typeName,
				currentType.memberTypes(),
				typesFound,
				receiverType,
				typeInvocation,
				staticOnly,
				staticFieldsAndMethodOnly,
				fromStaticImport,
				checkQualification,
				scope,
				missingElements,
				missingElementsStarts,
				missingElementsEnds,
				missingElementsHaveProblems);
			return;
		}

		ReferenceBinding[] interfacesToVisit = null;
		int nextPosition = 0;

		do {
			ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
			if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
				if (interfacesToVisit == null) {
					interfacesToVisit = itsInterfaces;
					nextPosition = interfacesToVisit.length;
				} else {
					int itsLength = itsInterfaces.length;
					if (nextPosition + itsLength >= interfacesToVisit.length)
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
					nextInterface : for (int a = 0; a < itsLength; a++) {
						ReferenceBinding next = itsInterfaces[a];
						for (int b = 0; b < nextPosition; b++)
							if (next == interfacesToVisit[b]) continue nextInterface;
						interfacesToVisit[nextPosition++] = next;
					}
				}
			}

			findMemberTypes(
				typeName,
				currentType.memberTypes(),
				typesFound,
				receiverType,
				typeInvocation,
				staticOnly,
				staticFieldsAndMethodOnly,
				fromStaticImport,
				checkQualification,
				scope,
				missingElements,
				missingElementsStarts,
				missingElementsEnds,
				missingElementsHaveProblems);

			currentType = currentType.superclass();
		} while (currentType != null);

		if(proposeAllMemberTypes) {
			ReferenceBinding[] memberTypes = receiverType.memberTypes();
			for (int i = 0; i < memberTypes.length; i++) {
				if(memberTypes[i] != typeToIgnore) {
					findSubMemberTypes(
						typeName,
						memberTypes[i],
						scope,
						typeInvocation,
						staticOnly,
						staticFieldsAndMethodOnly,
						fromStaticImport,
						typesFound);
				}
			}
		}

		if (interfacesToVisit != null) {
			for (int i = 0; i < nextPosition; i++) {
				ReferenceBinding anInterface = interfacesToVisit[i];
				findMemberTypes(
					typeName,
					anInterface.memberTypes(),
					typesFound,
					receiverType,
					typeInvocation,
					staticOnly,
					staticFieldsAndMethodOnly,
					fromStaticImport,
					checkQualification,
					scope,
					missingElements,
					missingElementsStarts,
					missingElementsEnds,
					missingElementsHaveProblems);

				ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
				if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
					int itsLength = itsInterfaces.length;
					if (nextPosition + itsLength >= interfacesToVisit.length)
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
					nextInterface : for (int a = 0; a < itsLength; a++) {
						ReferenceBinding next = itsInterfaces[a];
						for (int b = 0; b < nextPosition; b++)
							if (next == interfacesToVisit[b]) continue nextInterface;
						interfacesToVisit[nextPosition++] = next;
					}
				}
			}
		}
	}

	protected void findMemberTypes(
		char[] typeName,
		ReferenceBinding receiverType,
		Scope scope,
		SourceTypeBinding typeInvocation,
		boolean staticOnly,
		boolean staticFieldsAndMethodOnly,
		ObjectVector typesFound,
		Binding[] missingElements,
		int[] missingElementsStarts,
		int[] missingElementsEnds,
		boolean missingElementsHaveProblems)  {
		findMemberTypes(
				typeName,
				receiverType,
				scope,
				typeInvocation,
				staticOnly,
				staticFieldsAndMethodOnly,
				false,
				false,
				false,
				null,
				typesFound,
				missingElements,
				missingElementsStarts,
				missingElementsEnds,
				missingElementsHaveProblems);
	}
		// Helper method for findMemberTypes(char[], ReferenceBinding, Scope)
	private void findMemberTypes(
		char[] typeName,
		ReferenceBinding[] memberTypes,
		ObjectVector typesFound,
		ReferenceBinding receiverType,
		SourceTypeBinding invocationType,
		boolean staticOnly,
		boolean staticFieldsAndMethodOnly,
		boolean fromStaticImport,
		boolean checkQualification,
		Scope scope,
		Binding[] missingElements,
		int[] missingElementsStarts,
		int[] missingElementsEnds,
		boolean missingElementsHaveProblems) {

		// Inherited member types which are hidden by subclasses are filtered out
		// No visibility checks can be performed without the scope & invocationSite
		int typeLength = typeName.length;
		next : for (int m = memberTypes.length; --m >= 0;) {
			ReferenceBinding memberType = memberTypes[m];
			//		if (!wantClasses && memberType.isClass()) continue next;
			//		if (!wantInterfaces && memberType.isInterface()) continue next;

			if (staticOnly && !memberType.isStatic()) continue next;

			if (isForbidden(memberType)) continue next;

			if (typeLength > memberType.sourceName.length)
				continue next;

			if (!CharOperation.prefixEquals(typeName, memberType.sourceName, false/* ignore case */)
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, memberType.sourceName)))
				continue next;

			if (this.options.checkDeprecation &&
					memberType.isViewedAsDeprecated() &&
					!scope.isDefinedInSameUnit(memberType))
				continue next;

			if (this.options.checkVisibility) {
				if (invocationType != null && !memberType.canBeSeenBy(receiverType, invocationType)) {
					continue next;
				} else if(invocationType == null && !memberType.canBeSeenBy(this.unitScope.fPackage)) {
					continue next;
				}
			}

			if (this.insideQualifiedReference &&
					receiverType.isParameterizedType() &&
					memberType.isStatic()) {
				continue next;
			}

			for (int i = typesFound.size; --i >= 0;) {
				ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(i);

				if (memberType == otherType)
					continue next;

				if (CharOperation.equals(memberType.sourceName, otherType.sourceName, true)) {

					if (memberType.enclosingType().isSuperclassOf(otherType.enclosingType()))
						continue next;

					if (otherType.enclosingType().isInterface())
						if (memberType.enclosingType()
							.implementsInterface(otherType.enclosingType(), true))
							continue next;

					if (memberType.enclosingType().isInterface())
						if (otherType.enclosingType()
							.implementsInterface(memberType.enclosingType(), true))
							continue next;
				}
			}

			typesFound.add(memberType);

			if (this.assistNodeIsExtendedType && memberType.isFinal()) continue next;
			if (this.assistNodeIsInterfaceExcludingAnnotation && memberType.isAnnotationType()) continue next;
			if(!this.insideQualifiedReference) {
				if(this.assistNodeIsClass) {
					if(!memberType.isClass()) continue next;
				} else if(this.assistNodeIsInterface) {
					if(!memberType.isInterface() && !memberType.isAnnotationType()) continue next;
				} else if (this.assistNodeIsAnnotation) {
					if(!memberType.isAnnotationType()) continue next;
				}
			}

			char[] completionName = memberType.sourceName();

			boolean isQualified = false;
			if(checkQualification && !fromStaticImport) {
				char[] memberPackageName = memberType.qualifiedPackageName();
				char[] memberTypeName = memberType.sourceName();
				char[] memberEnclosingTypeNames = memberType.enclosingType().qualifiedSourceName();
				if (mustQualifyType(memberPackageName, memberTypeName, memberEnclosingTypeNames, memberType.modifiers)) {
					if (memberPackageName == null || memberPackageName.length == 0)
						if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
							break next; // ignore types from the default package from outside it
					isQualified = true;
					completionName =
						CharOperation.concat(
								memberPackageName,
								CharOperation.concat(
										memberEnclosingTypeNames,
										memberTypeName,
										'.'),
								'.');
				}
			}

			int relevance = computeBaseRelevance();
			relevance += computeRelevanceForResolution();
			relevance += computeRelevanceForInterestingProposal();
			relevance += computeRelevanceForCaseMatching(typeName, memberType.sourceName);
			relevance += computeRelevanceForExpectingType(memberType);
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
			if(!this.insideQualifiedReference) {
				relevance += computeRelevanceForQualification(isQualified);
			}
			if (staticFieldsAndMethodOnly && this.insideQualifiedReference) relevance += R_NON_INHERITED; // This criterion doesn't concern types and is added to be balanced with field and method relevance.

			if (memberType.isAnnotationType()) {
				relevance += computeRelevanceForAnnotation();
				relevance += computeRelevanceForAnnotationTarget(memberType);
			} else if (memberType.isClass()) {
				relevance += computeRelevanceForClass();
				relevance += computeRelevanceForException(memberType.sourceName);
			} else if(memberType.isEnum()) {
				relevance += computeRelevanceForEnum();
			} else if(memberType.isInterface()) {
				relevance += computeRelevanceForInterface();
			}

			if (missingElements != null) {
				relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
			}

			boolean allowingLongComputationProposals = isAllowingLongComputationProposals();
			
			this.noProposal = false;
			if (!this.assistNodeIsConstructor ||
					!allowingLongComputationProposals ||
					hasStaticMemberTypes(memberType, invocationType, this.unitScope) ||
					(memberType instanceof SourceTypeBinding && hasMemberTypesInEnclosingScope((SourceTypeBinding)memberType, scope)) ||
					hasArrayTypeAsExpectedSuperTypes()) {
				createTypeProposal(
						memberType,
						memberType.qualifiedSourceName(),
						IAccessRule.K_ACCESSIBLE,
						completionName,
						relevance,
						missingElements,
						missingElementsStarts,
						missingElementsEnds,
						missingElementsHaveProblems);
			}
			
			if (this.assistNodeIsConstructor && allowingLongComputationProposals) {
				findConstructorsOrAnonymousTypes(
						memberType,
						scope,
						FakeInvocationSite,
						isQualified,
						relevance);
			}
		}
	}
	private void findMemberTypesFromMissingType(
			char[] typeName,
			final long pos,
			final Scope scope)  {
		MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this);
		MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor =
			new MissingTypesGuesser.GuessedTypeRequestor() {
				public void accept(
						TypeBinding guessedType,
						Binding[] missingElements,
						int[] missingElementsStarts,
						int[] missingElementsEnds,
						boolean hasProblems) {
					if (guessedType instanceof ReferenceBinding) {
						findMemberTypes(
								CompletionEngine.this.completionToken,
								(ReferenceBinding)guessedType,
								scope,
								scope.enclosingSourceType(),
								false,
								false,
								new ObjectVector(),
								missingElements,
								missingElementsStarts,
								missingElementsEnds,
								hasProblems);
					}
				}
			};
		SingleTypeReference typeRef = new SingleTypeReference(typeName, pos);
		typeRef.resolvedType = new ProblemReferenceBinding(new char[][]{ typeName }, null, ProblemReasons.NotFound);
		missingTypesConverter.guess(typeRef, scope, substitutionRequestor);
	}
	
	private void findMemberTypesFromMissingType(
			TypeReference typeRef,
			final long pos,
			final Scope scope)  {
		MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this);
		MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor =
			new MissingTypesGuesser.GuessedTypeRequestor() {
				public void accept(
						TypeBinding guessedType,
						Binding[] missingElements,
						int[] missingElementsStarts,
						int[] missingElementsEnds,
						boolean hasProblems) {
					if (guessedType instanceof ReferenceBinding) {
						findMemberTypes(
								CompletionEngine.this.completionToken,
								(ReferenceBinding)guessedType,
								scope,
								scope.enclosingSourceType(),
								false,
								false,
								new ObjectVector(),
								missingElements,
								missingElementsStarts,
								missingElementsEnds,
								hasProblems);
					}
				}
			};
		missingTypesConverter.guess(typeRef, scope, substitutionRequestor);
	}

	private void findMethodDeclarations(
		char[] selector,
		ReferenceBinding receiverType,
		Scope scope,
		ObjectVector methodsFound,
		Binding[] missingElements,
		int[] missingElementsStarts,
		int[] missingElementsEnds,
		boolean missingElementsHaveProblems) {

		if (selector == null) {
			return;
		}

		MethodBinding[] receiverTypeMethods = receiverType.availableMethods();
		if (receiverTypeMethods != null){
			for (int i = 0; i < receiverTypeMethods.length; i++) {
				if(!receiverTypeMethods[i].isDefaultAbstract()) {
					methodsFound.add(receiverTypeMethods[i]);
				}
			}
		}

		ReferenceBinding currentType = receiverType;
		
		findInterfacesMethodDeclarations(
			selector,
			receiverType,
			currentType.superInterfaces(),
			scope,
			methodsFound,
			missingElements,
			missingElementsStarts,
			missingElementsEnds,
			missingElementsHaveProblems);
		
		if (receiverType.isInterface()) {
			currentType = scope.getJavaLangObject();
		} else {
			currentType = receiverType.superclass();
		}
		
		boolean hasPotentialDefaultAbstractMethods = true;
		while (currentType != null) {

			MethodBinding[] methods = currentType.availableMethods();
			if (methods != null) {
				findLocalMethodDeclarations(
					selector,
					methods,
					scope,
					methodsFound,
					false,
					receiverType);
			}

			if (hasPotentialDefaultAbstractMethods &&
					(currentType.isAbstract() ||
							currentType.isTypeVariable() ||
							currentType.isIntersectionType() ||
							currentType.isEnum())){

				ReferenceBinding[] superInterfaces = currentType.superInterfaces();

				findInterfacesMethodDeclarations(
					selector,
					receiverType,
					superInterfaces,
					scope,
					methodsFound,
					missingElements,
					missingElementsStarts,
					missingElementsEnds,
					missingElementsHaveProblems);
			} else {
				hasPotentialDefaultAbstractMethods = false;
			}
			currentType = currentType.superclass();
		}
	}
	
	private char[][] findMethodParameterNames(MethodBinding method, char[][] parameterTypeNames){
		TypeBinding erasure =  method.declaringClass.erasure();
		if(!(erasure instanceof ReferenceBinding)) return null;

		char[][] parameterNames = null;

		int length = parameterTypeNames.length;

		if (length == 0){
			return CharOperation.NO_CHAR_CHAR;
		}
		// look into the corresponding unit if it is available
		if (erasure instanceof SourceTypeBinding){
			SourceTypeBinding sourceType = (SourceTypeBinding) erasure;

			if (sourceType.scope != null){
				TypeDeclaration parsedType;

				if ((parsedType = sourceType.scope.referenceContext) != null){
					AbstractMethodDeclaration methodDecl = parsedType.declarationOf(method.original());

					if (methodDecl != null){
						Argument[] arguments = methodDecl.arguments;
						parameterNames = new char[length][];

						for(int i = 0 ; i < length ; i++){
							parameterNames[i] = arguments[i].name;
						}
					}
				}
			}
		}
		// look into the model
		if(parameterNames == null){

			ReferenceBinding bindingType = (ReferenceBinding)erasure;

			char[] compoundName = CharOperation.concatWith(bindingType.compoundName, '.');
			Object type = this.typeCache.get(compoundName);

			ISourceType sourceType = null;
			if(type != null) {
				if(type instanceof ISourceType) {
					sourceType = (ISourceType) type;
				}
			} else {
				NameEnvironmentAnswer answer = this.nameEnvironment.findType(bindingType.compoundName);
				if(answer != null && answer.isSourceType()) {
					sourceType = answer.getSourceTypes()[0];
					this.typeCache.put(compoundName, sourceType);
				}
			}

			if(sourceType != null) {
				IType typeHandle = ((SourceTypeElementInfo) sourceType).getHandle();

				String[] parameterTypeSignatures = new String[length];
				for (int i = 0; i < length; i++) {
					parameterTypeSignatures[i] = Signature.createTypeSignature(parameterTypeNames[i], false);
				}
				IMethod searchedMethod = typeHandle.getMethod(String.valueOf(method.selector), parameterTypeSignatures);
				IMethod[] foundMethods = typeHandle.findMethods(searchedMethod);

				if(foundMethods != null) {
					int len = foundMethods.length;
					if(len == 1) {
						try {
							SourceMethod sourceMethod = (SourceMethod) foundMethods[0];
							parameterNames = ((SourceMethodElementInfo) sourceMethod.getElementInfo()).getArgumentNames();
						} catch (JavaModelException e) {
							// method doesn't exist: ignore
						}
					}
				}
			}
		}
		return parameterNames;
	}

	private void findMethods(
		char[] selector,
		TypeBinding[] typeArgTypes,
		TypeBinding[] argTypes,
		ReferenceBinding receiverType,
		Scope scope,
		ObjectVector methodsFound,
		boolean onlyStaticMethods,
		boolean exactMatch,
		InvocationSite invocationSite,
		Scope invocationScope,
		boolean implicitCall,
		boolean superCall,
		boolean canBePrefixed,
		Binding[] missingElements,
		int[] missingElementsStarts,
		int[] missingElementsEnds,
		boolean missingElementsHaveProblems,
		char[] castedReceiver,
		int receiverStart,
		int receiverEnd) {

		boolean notInJavadoc = this.assistNodeInJavadoc == 0;
		if (selector == null && notInJavadoc) {
			return;
		}

		ReferenceBinding currentType = receiverType;
		if (notInJavadoc) {
			if (receiverType.isInterface()) {
				findInterfacesMethods(
					selector,
					typeArgTypes,
					argTypes,
					receiverType,
					new ReferenceBinding[]{currentType},
					scope,
					methodsFound,
					onlyStaticMethods,
					exactMatch,
					invocationSite,
					invocationScope,
					implicitCall,
					superCall,
					canBePrefixed,
					missingElements,
					missingElementsStarts,
					missingElementsEnds,
					missingElementsHaveProblems,
					castedReceiver,
					receiverStart,
					receiverEnd);

				currentType = scope.getJavaLangObject();
			}
		}
		boolean hasPotentialDefaultAbstractMethods = true;
		while (currentType != null) {

			MethodBinding[] methods = currentType.availableMethods();
			if (methods != null) {
				findLocalMethods(
					selector,
					typeArgTypes,
					argTypes,
					methods,
					scope,
					methodsFound,
					onlyStaticMethods,
					exactMatch,
					receiverType,
					invocationSite,
					invocationScope,
					implicitCall,
					superCall,
					canBePrefixed,
					missingElements,
					missingElementsStarts,
					missingElementsEnds,
					missingElementsHaveProblems,
					castedReceiver,
					receiverStart,
					receiverEnd);
			}

			if (hasPotentialDefaultAbstractMethods &&
					(currentType.isAbstract() ||
							currentType.isTypeVariable() ||
							currentType.isIntersectionType() ||
							currentType.isEnum())){

				ReferenceBinding[] superInterfaces = currentType.superInterfaces();
				if (superInterfaces != null && currentType.isIntersectionType()) {
					for (int i = 0; i < superInterfaces.length; i++) {
						superInterfaces[i] = (ReferenceBinding)superInterfaces[i].capture(invocationScope, invocationSite.sourceEnd());
					}
				}

				findInterfacesMethods(
					selector,
					typeArgTypes,
					argTypes,
					receiverType,
					superInterfaces,
					scope,
					methodsFound,
					onlyStaticMethods,
					exactMatch,
					invocationSite,
					invocationScope,
					implicitCall,
					superCall,
					canBePrefixed,
					missingElements,
					missingElementsStarts,
					missingElementsEnds,
					missingElementsHaveProblems,
					castedReceiver,
					receiverStart,
					receiverEnd);
			} else {
				hasPotentialDefaultAbstractMethods = false;
			}
			currentType = currentType.superclass();
		}
	}

	private void findNestedTypes(
		char[] typeName,
		SourceTypeBinding currentType,
		Scope scope,
		boolean proposeAllMemberTypes,
		ObjectVector typesFound) {
		
		if (typeName == null)
			return;

		int typeLength = typeName.length;

		SourceTypeBinding nextTypeToIgnore = null;
		while (scope != null) { // done when a COMPILATION_UNIT_SCOPE is found

			switch (scope.kind) {

				case Scope.METHOD_SCOPE :
				case Scope.BLOCK_SCOPE :
					BlockScope blockScope = (BlockScope) scope;

					next : for (int i = 0, length = blockScope.subscopeCount; i < length; i++) {

						if (blockScope.subscopes[i] instanceof ClassScope) {
							SourceTypeBinding localType =
								((ClassScope) blockScope.subscopes[i]).referenceContext.binding;

							if (!localType.isAnonymousType()) {
								if (isForbidden(localType))
									continue next;

								if (typeLength > localType.sourceName.length)
									continue next;
								if (!CharOperation.prefixEquals(typeName, localType.sourceName, false/* ignore case */)
										&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, localType.sourceName)))
									continue next;

								for (int j = typesFound.size; --j >= 0;) {
									ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(j);

									if (localType == otherType)
										continue next;
								}

								if (this.assistNodeIsExtendedType && localType.isFinal()) continue next;
								if (this.assistNodeIsInterfaceExcludingAnnotation && localType.isAnnotationType()) continue next;
								if(this.assistNodeIsClass) {
									if(!localType.isClass()) continue next;
								} else if(this.assistNodeIsInterface) {
									if(!localType.isInterface() && !localType.isAnnotationType()) continue next;
								} else if (this.assistNodeIsAnnotation) {
									if(!localType.isAnnotationType()) continue next;
								}

								int relevance = computeBaseRelevance();
								relevance += computeRelevanceForResolution();
								relevance += computeRelevanceForInterestingProposal();
								relevance += computeRelevanceForCaseMatching(typeName, localType.sourceName);
								relevance += computeRelevanceForExpectingType(localType);
								relevance += computeRelevanceForException(localType.sourceName);
								relevance += computeRelevanceForClass();
								relevance += computeRelevanceForQualification(false);
								relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for nested type
								relevance += computeRelevanceForAnnotationTarget(localType);

								boolean allowingLongComputationProposals = isAllowingLongComputationProposals();
								if (!this.assistNodeIsConstructor || !allowingLongComputationProposals || hasArrayTypeAsExpectedSuperTypes()) {
									this.noProposal = false;
									if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
										createTypeProposal(
												localType,
												localType.sourceName,
												IAccessRule.K_ACCESSIBLE,
												localType.sourceName,
												relevance,
												null,
												null,
												null,
												false);
									}
								}
								
								if (this.assistNodeIsConstructor && allowingLongComputationProposals) {
									findConstructorsOrAnonymousTypes(
											localType,
											blockScope,
											FakeInvocationSite,
											false,
											relevance);
								}
							}
						}
					}
					break;

				case Scope.CLASS_SCOPE :
					SourceTypeBinding enclosingSourceType = scope.enclosingSourceType();
					findMemberTypes(
							typeName,
							enclosingSourceType,
							scope,
							currentType,
							false,
							false,
							false,
							false,
							proposeAllMemberTypes,
							nextTypeToIgnore,
							typesFound,
							null,
							null,
							null,
							false);
					nextTypeToIgnore = enclosingSourceType;
					if (typeLength == 0)
						return; // do not search outside the class scope if no prefix was provided
					break;

				case Scope.COMPILATION_UNIT_SCOPE :
					return;
			}
			scope = scope.parent;
		}
	}

	private void findPackages(CompletionOnPackageReference packageStatement) {

		this.completionToken = CharOperation.concatWith(packageStatement.tokens, '.');
		if (this.completionToken.length == 0)
			return;

		setSourceRange(packageStatement.sourceStart, packageStatement.sourceEnd);
		long completionPosition = packageStatement.sourcePositions[packageStatement.sourcePositions.length - 1];
		setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
		this.nameEnvironment.findPackages(CharOperation.toLowerCase(this.completionToken), this);
	}

	private void findParameterizedType(TypeReference ref, Scope scope) {
		ReferenceBinding refBinding = (ReferenceBinding) ref.resolvedType;
		if(refBinding != null) {
			if (this.options.checkDeprecation &&
					refBinding.isViewedAsDeprecated() &&
					!scope.isDefinedInSameUnit(refBinding))
				return;

			int accessibility = IAccessRule.K_ACCESSIBLE;
			if(refBinding.hasRestrictedAccess()) {
				AccessRestriction accessRestriction = this.lookupEnvironment.getAccessRestriction(refBinding);
				if(accessRestriction != null) {
					switch (accessRestriction.getProblemId()) {
						case IProblem.ForbiddenReference:
							if (this.options.checkForbiddenReference) {
								return;
							}
							accessibility = IAccessRule.K_NON_ACCESSIBLE;
							break;
						case IProblem.DiscouragedReference:
							if (this.options.checkDiscouragedReference) {
								return;
							}
							accessibility = IAccessRule.K_DISCOURAGED;
							break;
					}
				}
			}

			int relevance = computeBaseRelevance();
			relevance += computeRelevanceForResolution();
			relevance += computeRelevanceForInterestingProposal();
			relevance += computeRelevanceForCaseMatching(refBinding.sourceName, refBinding.sourceName);
			relevance += computeRelevanceForExpectingType(refBinding);
			relevance += computeRelevanceForQualification(false);
			relevance += computeRelevanceForRestrictions(accessibility); // no access restriction for type in the current unit

			if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
				createTypeProposal(
						refBinding,
						refBinding.qualifiedSourceName(),
						IAccessRule.K_ACCESSIBLE,
						CharOperation.NO_CHAR,
						relevance,
						null,
						null,
						null,
						false);
			}
		}
	}

	private void findSubMemberTypes(
		char[] typeName,
		ReferenceBinding receiverType,
		Scope scope,
		SourceTypeBinding typeInvocation,
		boolean staticOnly,
		boolean staticFieldsAndMethodOnly,
		boolean fromStaticImport,
		ObjectVector typesFound) {

		ReferenceBinding currentType = receiverType;
		if (typeName == null)
			return;

		if (this.assistNodeIsSuperType && !this.insideQualifiedReference && isForbidden(currentType)) return; // we're trying to find a supertype

		findMemberTypes(
				typeName,
				currentType.memberTypes(),
				typesFound,
				receiverType,
				typeInvocation,
				staticOnly,
				staticFieldsAndMethodOnly,
				fromStaticImport,
				true,
				scope,
				null,
				null,
				null,
				false);

		ReferenceBinding[] memberTypes = receiverType.memberTypes();
		next : for (int i = 0; i < memberTypes.length; i++) {
			if (this.options.checkVisibility) {
				if (typeInvocation != null && !memberTypes[i].canBeSeenBy(receiverType, typeInvocation)) {
					continue next;
				} else if(typeInvocation == null && !memberTypes[i].canBeSeenBy(this.unitScope.fPackage)) {
					continue next;
				}
			}
			findSubMemberTypes(
				typeName,
				memberTypes[i],
				scope,
				typeInvocation,
				staticOnly,
				staticFieldsAndMethodOnly,
				fromStaticImport,
				typesFound);
		}
	}

	private void findTrueOrFalseKeywords(char[][] choices) {
		if(choices == null || choices.length == 0) return;

		if(this.expectedTypesPtr != 0 || this.expectedTypes[0] != TypeBinding.BOOLEAN) return;

		for (int i = 0; i < choices.length; i++) {
			if (CharOperation.equals(choices[i], Keywords.TRUE) ||
					CharOperation.equals(choices[i], Keywords.FALSE)
			){
				int relevance = computeBaseRelevance();
				relevance += computeRelevanceForResolution();
				relevance += computeRelevanceForInterestingProposal();
				relevance += computeRelevanceForCaseMatching(CharOperation.NO_CHAR, choices[i]);
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywors
				relevance += computeRelevanceForExpectingType(TypeBinding.BOOLEAN);
				relevance += computeRelevanceForQualification(false);
				relevance += R_TRUE_OR_FALSE;

				this.noProposal = false;
				if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
					proposal.setName(choices[i]);
					proposal.setCompletion(choices[i]);
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
					proposal.setRelevance(relevance);
					this.requestor.accept(proposal);
					if(DEBUG) {
						this.printDebug(proposal);
					}
				}
			}
		}
	}

	private void findTypeParameters(char[] token, Scope scope) {
		if (this.compilerOptions.sourceLevel < ClassFileConstants.JDK1_5) return;

		TypeParameter[] typeParameters = null;
		while (scope != null) { // done when a COMPILATION_UNIT_SCOPE is found
			typeParameters = null;
			switch (scope.kind) {
				case Scope.METHOD_SCOPE :
					MethodScope methodScope = (MethodScope) scope;
					if(methodScope.referenceContext instanceof MethodDeclaration) {
						MethodDeclaration methodDeclaration = (MethodDeclaration) methodScope.referenceContext;
						typeParameters = methodDeclaration.typeParameters;
					} else if(methodScope.referenceContext instanceof ConstructorDeclaration) {
						ConstructorDeclaration methodDeclaration = (ConstructorDeclaration) methodScope.referenceContext;
						typeParameters = methodDeclaration.typeParameters;
					}
					break;
				case Scope.CLASS_SCOPE :
					ClassScope classScope = (ClassScope) scope;
					typeParameters = classScope.referenceContext.typeParameters;
					break;
				case Scope.COMPILATION_UNIT_SCOPE :
					return;
			}
			if(typeParameters != null) {
				for (int i = 0; i < typeParameters.length; i++) {
					int typeLength = token.length;
					TypeParameter typeParameter = typeParameters[i];

					if(typeParameter.binding == null) continue;

					if (typeLength > typeParameter.name.length) continue;

					if (!CharOperation.prefixEquals(token, typeParameter.name, false)
							&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, typeParameter.name))) continue;

					int relevance = computeBaseRelevance();
					relevance += computeRelevanceForResolution();
					relevance += computeRelevanceForInterestingProposal();
					relevance += computeRelevanceForCaseMatching(token, typeParameter.name);
					relevance += computeRelevanceForExpectingType(typeParameter.type == null ? null :typeParameter.type.resolvedType);
					relevance += computeRelevanceForQualification(false);
					relevance += computeRelevanceForException(typeParameter.name);
					relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction fot type parameter

					this.noProposal = false;
					if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
						createTypeParameterProposal(typeParameter, relevance);
					}
				}
			}
			scope = scope.parent;
		}
	}

	private void findTypesAndPackages(char[] token, Scope scope, boolean proposeBaseTypes, boolean proposeVoidType, ObjectVector typesFound) {

		if (token == null)
			return;
		
		boolean allowingLongComputationProposals = isAllowingLongComputationProposals();
		
		boolean proposeType =
			!this.requestor.isIgnored(CompletionProposal.TYPE_REF) ||
			((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF));

		boolean proposeAllMemberTypes = !this.assistNodeIsConstructor;
		
		boolean proposeConstructor =
			allowingLongComputationProposals &&
			this.assistNodeIsConstructor &&
			(!isIgnored(CompletionProposal.CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF) ||
					!isIgnored(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF));
		

		if ((proposeType || proposeConstructor) && scope.enclosingSourceType() != null) {
			
			checkCancel();
			
			findNestedTypes(token, scope.enclosingSourceType(), scope, proposeAllMemberTypes, typesFound);
			if(!this.assistNodeIsInterface &&
					!this.assistNodeIsConstructor &&
					!this.assistNodeIsAnnotation &&
					this.assistNodeInJavadoc == 0) {
				
				checkCancel();
				
				// don't propose type parameters if the completion is a constructor ('new |')
				findTypeParameters(token, scope);
			}
		}

		boolean isEmptyPrefix = token.length == 0;

		if ((proposeType || proposeConstructor) && this.unitScope != null) {
			
			ReferenceBinding outerInvocationType = scope.enclosingSourceType();
			if(outerInvocationType != null) {
				ReferenceBinding temp = outerInvocationType.enclosingType();
				while(temp != null) {
					outerInvocationType = temp;
					temp = temp.enclosingType();
				}
			}

			int typeLength = token.length;
			SourceTypeBinding[] types = this.unitScope.topLevelTypes;

			next : for (int i = 0, length = types.length; i < length; i++) {
				
				checkCancel();
				
				SourceTypeBinding sourceType = types[i];

				if(isForbidden(sourceType)) continue next;

				if(proposeAllMemberTypes &&
					sourceType != outerInvocationType) {
					findSubMemberTypes(
							token,
							sourceType,
							scope,
							scope.enclosingSourceType(),
							false,
							false,
							false,
							typesFound);
				}

				if (sourceType.sourceName == CompletionParser.FAKE_TYPE_NAME) continue next;
				if (sourceType.sourceName == TypeConstants.PACKAGE_INFO_NAME) continue next;

				if (typeLength > sourceType.sourceName.length) continue next;

				if (!CharOperation.prefixEquals(token, sourceType.sourceName, false)
						&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, sourceType.sourceName))) continue next;

				if (this.assistNodeIsAnnotation && !hasPossibleAnnotationTarget(sourceType, scope)) {
					continue next;
				}

				for (int j = typesFound.size; --j >= 0;) {
					ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(j);

					if (sourceType == otherType) continue next;
				}
				
				typesFound.add(sourceType);

				if (this.assistNodeIsExtendedType && sourceType.isFinal()) continue next;
				if (this.assistNodeIsInterfaceExcludingAnnotation && sourceType.isAnnotationType()) continue next;
				if(this.assistNodeIsClass) {
					if(!sourceType.isClass()) continue next;
				} else if(this.assistNodeIsInterface) {
					if(!sourceType.isInterface() && !sourceType.isAnnotationType()) continue next;
				} else if (this.assistNodeIsAnnotation) {
					if(!sourceType.isAnnotationType()) continue next;
				} else if (isEmptyPrefix && this.assistNodeIsException) {
					if (sourceType.findSuperTypeOriginatingFrom(TypeIds.T_JavaLangThrowable, true) == null) {
						continue next;
					}
				}

				int relevance = computeBaseRelevance();
				relevance += computeRelevanceForResolution();
				relevance += computeRelevanceForInterestingProposal();
				relevance += computeRelevanceForCaseMatching(token, sourceType.sourceName);
				relevance += computeRelevanceForExpectingType(sourceType);
				relevance += computeRelevanceForQualification(false);
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for type in the current unit

				if (sourceType.isAnnotationType()) {
					relevance += computeRelevanceForAnnotation();
					relevance += computeRelevanceForAnnotationTarget(sourceType);
				} else if (sourceType.isInterface()) {
					relevance += computeRelevanceForInterface();
				} else if(sourceType.isClass()){
					relevance += computeRelevanceForClass();
					relevance += computeRelevanceForException(sourceType.sourceName);
				}
				
				
				this.noProposal = false;
				if(proposeType &&
						(!this.assistNodeIsConstructor ||
								!allowingLongComputationProposals ||
								hasStaticMemberTypes(sourceType, null, this.unitScope) ||
								hasMemberTypesInEnclosingScope(sourceType, scope)) ||
								hasArrayTypeAsExpectedSuperTypes()) {
					char[] typeName = sourceType.sourceName();
					createTypeProposal(
							sourceType,
							typeName,
							IAccessRule.K_ACCESSIBLE,
							typeName,
							relevance,
							null,
							null,
							null,
							false);
				}
				
				if (proposeConstructor) {
					findConstructorsOrAnonymousTypes(
							sourceType,
							scope,
							FakeInvocationSite,
							false,
							relevance);
				}
			}
		}

		if (proposeConstructor && !isEmptyPrefix) {
			
			checkCancel();
			
			findTypesFromImports(token, scope, proposeType, typesFound);
		} else if(proposeType) {
			
			checkCancel();
			
			findTypesFromStaticImports(token, scope, proposeAllMemberTypes, typesFound);
		}
		
		if (proposeConstructor) {
			
			checkCancel();
			
			findTypesFromExpectedTypes(token, scope, typesFound, proposeType, proposeConstructor);
		}

		if (isEmptyPrefix && !this.assistNodeIsAnnotation) {
			if (!proposeConstructor) {
				findTypesFromExpectedTypes(token, scope, typesFound, proposeType, proposeConstructor);
			}
		} else {
			if(!isEmptyPrefix && !this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
				if (this.assistNodeInJavadoc == 0 || (this.assistNodeInJavadoc & CompletionOnJavadoc.BASE_TYPES) != 0) {
					if (proposeBaseTypes) {
						if (proposeVoidType) {
							findKeywords(token, BASE_TYPE_NAMES, false, false);
						} else {
							findKeywords(token, BASE_TYPE_NAMES_WITHOUT_VOID, false, false);
						}
					}
				}
			}
			
			if (proposeConstructor) {
				int l = typesFound.size();
				for (int i = 0; i < l; i++) {
					ReferenceBinding typeFound = (ReferenceBinding) typesFound.elementAt(i);
					char[] fullyQualifiedTypeName =
						CharOperation.concat(
								typeFound.qualifiedPackageName(),
								typeFound.qualifiedSourceName(),
								'.');
					this.knownTypes.put(fullyQualifiedTypeName, KNOWN_TYPE_WITH_KNOWN_CONSTRUCTORS);
				}
				
				checkCancel();
				
				this.foundConstructorsCount = 0;
				this.nameEnvironment.findConstructorDeclarations(
						token,
						this.options.camelCaseMatch,
						this,
						this.monitor);
				acceptConstructors(scope);
			} else if (proposeType) {
				int l = typesFound.size();
				for (int i = 0; i < l; i++) {
					ReferenceBinding typeFound = (ReferenceBinding) typesFound.elementAt(i);
					char[] fullyQualifiedTypeName =
						CharOperation.concat(
								typeFound.qualifiedPackageName(),
								typeFound.qualifiedSourceName(),
								'.');
					this.knownTypes.put(fullyQualifiedTypeName, KNOWN_TYPE_WITH_KNOWN_CONSTRUCTORS);
				}
				int searchFor = IJavaSearchConstants.TYPE;
				if(this.assistNodeIsClass) {
					searchFor = IJavaSearchConstants.CLASS;
				} else if (this.assistNodeIsInterfaceExcludingAnnotation) {
					searchFor = IJavaSearchConstants.INTERFACE;
				} else if(this.assistNodeIsInterface) {
					searchFor = IJavaSearchConstants.INTERFACE_AND_ANNOTATION;
				} else if(this.assistNodeIsEnum) {
					searchFor = IJavaSearchConstants.ENUM;
				} else if(this.assistNodeIsAnnotation) {
					searchFor = IJavaSearchConstants.ANNOTATION_TYPE;
				}
				
				checkCancel();
				
				this.foundTypesCount = 0;
				this.nameEnvironment.findTypes(
						token,
						proposeAllMemberTypes,
						this.options.camelCaseMatch,
						searchFor,
						this,
						this.monitor);
				acceptTypes(scope);
			}
			if(!isEmptyPrefix && !this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
				
				checkCancel();
				
				this.nameEnvironment.findPackages(token, this);
			}
		}
	}

	private void findTypesAndSubpackages(
		char[] token,
		PackageBinding packageBinding,
		Scope scope) {
		
		boolean allowingLongComputationProposals = isAllowingLongComputationProposals();

		boolean proposeType =
			!this.requestor.isIgnored(CompletionProposal.TYPE_REF) ||
			((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF));
		
		boolean proposeConstructor =
			allowingLongComputationProposals &&
			this.assistNodeIsConstructor &&
			(!isIgnored(CompletionProposal.CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF) ||
					!isIgnored(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF));

		char[] qualifiedName =
			CharOperation.concatWith(packageBinding.compoundName, token, '.');

		if (token == null || token.length == 0) {
			int length = qualifiedName.length;
			System.arraycopy(
				qualifiedName,
				0,
				qualifiedName = new char[length + 1],
				0,
				length);
			qualifiedName[length] = '.';
		}

		this.qualifiedCompletionToken = qualifiedName;

		if ((proposeType || proposeConstructor) && this.unitScope != null) {
			int typeLength = qualifiedName.length;
			SourceTypeBinding[] types = this.unitScope.topLevelTypes;

			for (int i = 0, length = types.length; i < length; i++) {
				
				checkCancel();
				
				SourceTypeBinding sourceType = types[i];
				
				if (isForbidden(sourceType)) continue;
				if (this.assistNodeIsClass && sourceType.isInterface()) continue;
				if (this.assistNodeIsInterface && sourceType.isClass()) continue;

				char[] qualifiedSourceTypeName = CharOperation.concatWith(sourceType.compoundName, '.');

				if (sourceType.sourceName == CompletionParser.FAKE_TYPE_NAME) continue;
				if (sourceType.sourceName == TypeConstants.PACKAGE_INFO_NAME) continue;
				if (typeLength > qualifiedSourceTypeName.length) continue;
				if (!(packageBinding == sourceType.getPackage())) continue;

				if (!CharOperation.prefixEquals(qualifiedName, qualifiedSourceTypeName, false)
						&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, sourceType.sourceName)))	continue;

				if (this.options.checkDeprecation &&
						sourceType.isViewedAsDeprecated() &&
						!scope.isDefinedInSameUnit(sourceType))
					continue;

			    if (this.assistNodeIsExtendedType && sourceType.isFinal()) continue;
			    if (this.assistNodeIsInterfaceExcludingAnnotation && sourceType.isAnnotationType()) continue;
				int accessibility = IAccessRule.K_ACCESSIBLE;
				if(sourceType.hasRestrictedAccess()) {
					AccessRestriction accessRestriction = this.lookupEnvironment.getAccessRestriction(sourceType);
					if(accessRestriction != null) {
						switch (accessRestriction.getProblemId()) {
							case IProblem.ForbiddenReference:
								if (this.options.checkForbiddenReference) {
									continue;
								}
								accessibility = IAccessRule.K_NON_ACCESSIBLE;
								break;
							case IProblem.DiscouragedReference:
								if (this.options.checkDiscouragedReference) {
									continue;
								}
								accessibility = IAccessRule.K_DISCOURAGED;
								break;
						}
					}
				}

				this.knownTypes.put(CharOperation.concat(sourceType.qualifiedPackageName(), sourceType.sourceName(), '.'), KNOWN_TYPE_WITH_KNOWN_CONSTRUCTORS);

				int relevance = computeBaseRelevance();
				relevance += computeRelevanceForResolution();
				relevance += computeRelevanceForInterestingProposal();
				relevance += computeRelevanceForCaseMatching(qualifiedName, qualifiedSourceTypeName);
				relevance += computeRelevanceForExpectingType(sourceType);
				relevance += computeRelevanceForQualification(false);
				relevance += computeRelevanceForRestrictions(accessibility);

				if (sourceType.isAnnotationType()) {
					relevance += computeRelevanceForAnnotation();
				} else if (sourceType.isInterface()) {
					relevance += computeRelevanceForInterface();
				} else if (sourceType.isClass()) {
					relevance += computeRelevanceForClass();
					relevance += computeRelevanceForException(sourceType.sourceName);
				}
				
				this.noProposal = false;
				if(proposeType &&
						(!this.assistNodeIsConstructor ||
								!allowingLongComputationProposals ||
								hasStaticMemberTypes(sourceType, null, this.unitScope) ||
								hasMemberTypesInEnclosingScope(sourceType, scope)) ||
								hasArrayTypeAsExpectedSuperTypes()) {
					char[] typeName = sourceType.sourceName();
					createTypeProposal(
							sourceType,
							typeName,
							IAccessRule.K_ACCESSIBLE,
							typeName,
							relevance,
							null,
							null,
							null,
							false);
				}
				
				if (proposeConstructor) {
					findConstructorsOrAnonymousTypes(
							sourceType,
							scope,
							FakeInvocationSite,
							false,
							relevance);
				}
			}
		}

		if (proposeConstructor) {

			
			checkCancel();
			
			this.foundConstructorsCount = 0;
			this.nameEnvironment.findConstructorDeclarations(
					qualifiedName,
					this.options.camelCaseMatch,
					this,
					this.monitor);
			acceptConstructors(scope);
		} if(proposeType) {
			int searchFor = IJavaSearchConstants.TYPE;
			if(this.assistNodeIsClass) {
				searchFor = IJavaSearchConstants.CLASS;
			} else if (this.assistNodeIsInterfaceExcludingAnnotation) {
				searchFor = IJavaSearchConstants.INTERFACE;
			} else if(this.assistNodeIsInterface) {
				searchFor = IJavaSearchConstants.INTERFACE_AND_ANNOTATION;
			} else if(this.assistNodeIsEnum) {
				searchFor = IJavaSearchConstants.ENUM;
			} else if(this.assistNodeIsAnnotation) {
				searchFor = IJavaSearchConstants.ANNOTATION_TYPE;
			}
			
			checkCancel();
			
			this.foundTypesCount = 0;
			this.nameEnvironment.findTypes(
					qualifiedName,
					false,
					this.options.camelCaseMatch,
					searchFor,
					this,
					this.monitor);
			acceptTypes(scope);
		}
		
		if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
			this.nameEnvironment.findPackages(qualifiedName, this);
		}
	}
	
	private void findTypesFromExpectedTypes(char[] token, Scope scope, ObjectVector typesFound, boolean proposeType, boolean proposeConstructor) {
		if(this.expectedTypesPtr > -1) {
			boolean allowingLongComputationProposals = isAllowingLongComputationProposals();
			
			int typeLength = token == null ? 0 : token.length;
			
			next : for (int i = 0; i <= this.expectedTypesPtr; i++) {
				
				checkCancel();
				
				if(this.expectedTypes[i] instanceof ReferenceBinding) {
					ReferenceBinding refBinding = (ReferenceBinding)this.expectedTypes[i];
					
					if (typeLength > 0) {
						if (typeLength > refBinding.sourceName.length) continue next;
	
						if (!CharOperation.prefixEquals(token, refBinding.sourceName, false)
								&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, refBinding.sourceName))) continue next;
					}


					if(refBinding.isTypeVariable() && this.assistNodeIsConstructor) {
						// don't propose type variable if the completion is a constructor ('new |')
						continue next;
					}
					if (this.options.checkDeprecation &&
							refBinding.isViewedAsDeprecated() &&
							!scope.isDefinedInSameUnit(refBinding))
						continue next;

					int accessibility = IAccessRule.K_ACCESSIBLE;
					if(refBinding.hasRestrictedAccess()) {
						AccessRestriction accessRestriction = this.lookupEnvironment.getAccessRestriction(refBinding);
						if(accessRestriction != null) {
							switch (accessRestriction.getProblemId()) {
								case IProblem.ForbiddenReference:
									if (this.options.checkForbiddenReference) {
										continue next;
									}
									accessibility = IAccessRule.K_NON_ACCESSIBLE;
									break;
								case IProblem.DiscouragedReference:
									if (this.options.checkDiscouragedReference) {
										continue next;
									}
									accessibility = IAccessRule.K_DISCOURAGED;
									break;
							}
						}
					}

					for (int j = 0; j < typesFound.size(); j++) {
						ReferenceBinding typeFound = (ReferenceBinding)typesFound.elementAt(j);
						if (typeFound == refBinding.erasure()) {
							continue next;
						}
					}
					
					typesFound.add(refBinding);

					boolean inSameUnit = this.unitScope.isDefinedInSameUnit(refBinding);

					// top level types of the current unit are already proposed.
					if(!inSameUnit || (inSameUnit && refBinding.isMemberType())) {
						char[] packageName = refBinding.qualifiedPackageName();
						char[] typeName = refBinding.sourceName();
						char[] completionName = typeName;

						boolean isQualified = false;
						if (!this.insideQualifiedReference && !refBinding.isMemberType()) {
							if (mustQualifyType(packageName, typeName, null, refBinding.modifiers)) {
								if (packageName == null || packageName.length == 0)
									if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
										continue next; // ignore types from the default package from outside it
								completionName = CharOperation.concat(packageName, typeName, '.');
								isQualified = true;
							}
						}

						if (this.assistNodeIsExtendedType && refBinding.isFinal()) continue next;
						if (this.assistNodeIsInterfaceExcludingAnnotation && refBinding.isAnnotationType()) continue next;
						if(this.assistNodeIsClass) {
							if(!refBinding.isClass()) continue next;
						} else if(this.assistNodeIsInterface) {
							if(!refBinding.isInterface() && !refBinding.isAnnotationType()) continue next;
						} else if (this.assistNodeIsAnnotation) {
							if(!refBinding.isAnnotationType()) continue next;
						}

						int relevance = computeBaseRelevance();
						relevance += computeRelevanceForResolution();
						relevance += computeRelevanceForInterestingProposal();
						relevance += computeRelevanceForCaseMatching(token, typeName);
						relevance += computeRelevanceForExpectingType(refBinding);
						relevance += computeRelevanceForQualification(isQualified);
						relevance += computeRelevanceForRestrictions(accessibility);

						if(refBinding.isClass()) {
							relevance += computeRelevanceForClass();
							relevance += computeRelevanceForException(typeName);
						} else if(refBinding.isEnum()) {
							relevance += computeRelevanceForEnum();
						} else if(refBinding.isInterface()) {
							relevance += computeRelevanceForInterface();
						}
						
						if (proposeType &&
								(!this.assistNodeIsConstructor ||
										!allowingLongComputationProposals ||
										hasStaticMemberTypes(refBinding, scope.enclosingSourceType() ,this.unitScope)) ||
										hasArrayTypeAsExpectedSuperTypes()) {
							this.noProposal = false;
							if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
								InternalCompletionProposal proposal =  createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
								proposal.setDeclarationSignature(packageName);
								proposal.setSignature(getSignature(refBinding));
								proposal.setPackageName(packageName);
								proposal.setTypeName(typeName);
								proposal.setCompletion(completionName);
								proposal.setFlags(refBinding.modifiers);
								proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
								proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
								proposal.setRelevance(relevance);
								proposal.setAccessibility(accessibility);
								this.requestor.accept(proposal);
								if(DEBUG) {
									this.printDebug(proposal);
								}
							}
						}
						
						if (proposeConstructor) {
							findConstructorsOrAnonymousTypes(
									refBinding,
									scope,
									FakeInvocationSite,
									isQualified,
									relevance);
						}
					}
				}
			}
		}
	}

	private void findTypesFromImports(char[] token, Scope scope, boolean proposeType, ObjectVector typesFound) {
		ImportBinding[] importBindings = scope.compilationUnitScope().imports;
		next : for (int i = 0; i < importBindings.length; i++) {
			ImportBinding importBinding = importBindings[i];
			if(importBinding.isValidBinding()) {
				Binding binding = importBinding.resolvedImport;
				if(binding != null && binding.isValidBinding()) {
					if(importBinding.onDemand) {
						if (importBinding.isStatic()) {
							if((binding.kind() & Binding.TYPE) != 0) {
								this.findMemberTypes(
										token,
										(ReferenceBinding) binding,
										scope,
										scope.enclosingSourceType(),
										true,
										false,
										true,
										true,
										false,
										null,
										typesFound,
										null,
										null,
										null,
										false);
							}
						}
					} else {
						if ((binding.kind() & Binding.TYPE) != 0) {
							ReferenceBinding typeBinding = (ReferenceBinding) binding;
							int typeLength = token.length;

							if (!typeBinding.isStatic()) continue next;

							if (typeLength > typeBinding.sourceName.length)	continue next;

							if (!CharOperation.prefixEquals(token, typeBinding.sourceName, false)
									&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, typeBinding.sourceName))) continue next;
							
							int accessibility = IAccessRule.K_ACCESSIBLE;
							if(typeBinding.hasRestrictedAccess()) {
								AccessRestriction accessRestriction = this.lookupEnvironment.getAccessRestriction(typeBinding);
								if(accessRestriction != null) {
									switch (accessRestriction.getProblemId()) {
										case IProblem.ForbiddenReference:
											if (this.options.checkForbiddenReference) {
												continue next;
											}
											accessibility = IAccessRule.K_NON_ACCESSIBLE;
											break;
										case IProblem.DiscouragedReference:
											if (this.options.checkDiscouragedReference) {
												continue next;
											}
											accessibility = IAccessRule.K_DISCOURAGED;
											break;
									}
								}
							}
							
							if (typesFound.contains(typeBinding)) continue next;
							
							typesFound.add(typeBinding);
							
							if (this.assistNodeIsExtendedType && typeBinding.isFinal()) continue;
							if (this.assistNodeIsInterfaceExcludingAnnotation && typeBinding.isAnnotationType()) continue;
							if(this.assistNodeIsClass) {
								if(!typeBinding.isClass()) continue;
							} else if(this.assistNodeIsInterface) {
								if(!typeBinding.isInterface() && !typeBinding.isAnnotationType()) continue;
							} else if (this.assistNodeIsAnnotation) {
								if(!typeBinding.isAnnotationType()) continue;
							}
							
							int relevance = computeBaseRelevance();
							relevance += computeRelevanceForResolution();
							relevance += computeRelevanceForInterestingProposal();
							relevance += computeRelevanceForCaseMatching(token, typeBinding.sourceName);
							relevance += computeRelevanceForExpectingType(typeBinding);
							relevance += computeRelevanceForQualification(false);
							relevance += computeRelevanceForRestrictions(accessibility);
			
							if (typeBinding.isAnnotationType()) {
								relevance += computeRelevanceForAnnotation();
								relevance += computeRelevanceForAnnotationTarget(typeBinding);
							} else if (typeBinding.isInterface()) {
								relevance += computeRelevanceForInterface();
							} else if(typeBinding.isClass()){
								relevance += computeRelevanceForClass();
								relevance += computeRelevanceForException(typeBinding.sourceName);
							}
							
							if (proposeType && 
									(hasStaticMemberTypes(typeBinding, scope.enclosingSourceType(), this.unitScope) || hasArrayTypeAsExpectedSuperTypes())) {
								this.noProposal = false;
								if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
									InternalCompletionProposal proposal =  createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
									proposal.setDeclarationSignature(typeBinding.qualifiedPackageName());
									proposal.setSignature(getSignature(typeBinding));
									proposal.setPackageName(typeBinding.qualifiedPackageName());
									proposal.setTypeName(typeBinding.qualifiedSourceName());
									proposal.setCompletion(typeBinding.sourceName());
									proposal.setFlags(typeBinding.modifiers);
									proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
									proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
									proposal.setRelevance(relevance);
									this.requestor.accept(proposal);
									if(DEBUG) {
										this.printDebug(proposal);
									}
								}
							}
							
							findConstructorsOrAnonymousTypes(
									typeBinding,
									scope,
									FakeInvocationSite,
									false,
									relevance);
						}
					}
				}
			}
		}
	}
	
	private void findTypesFromStaticImports(char[] token, Scope scope, boolean proposeAllMemberTypes, ObjectVector typesFound) {
		ImportBinding[] importBindings = scope.compilationUnitScope().imports;
		for (int i = 0; i < importBindings.length; i++) {
			ImportBinding importBinding = importBindings[i];
			if(importBinding.isValidBinding() && importBinding.isStatic()) {
				Binding binding = importBinding.resolvedImport;
				if(binding != null && binding.isValidBinding()) {
					if(importBinding.onDemand) {
						if((binding.kind() & Binding.TYPE) != 0) {
							this.findMemberTypes(
									token,
									(ReferenceBinding) binding,
									scope,
									scope.enclosingSourceType(),
									true,
									false,
									true,
									true,
									proposeAllMemberTypes,
									null,
									typesFound,
									null,
									null,
									null,
									false);
						}
					} else {
						if ((binding.kind() & Binding.TYPE) != 0) {
							ReferenceBinding typeBinding = (ReferenceBinding) binding;
							int typeLength = token.length;

							if (!typeBinding.isStatic()) continue;

							if (typeLength > typeBinding.sourceName.length)	continue;

							if (!CharOperation.prefixEquals(token, typeBinding.sourceName, false)
									&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, typeBinding.sourceName)))	continue;

							if (typesFound.contains(typeBinding))  continue;

							typesFound.add(typeBinding);

							if (this.assistNodeIsExtendedType && typeBinding.isFinal()) continue;
							if (this.assistNodeIsInterfaceExcludingAnnotation && typeBinding.isAnnotationType()) continue;
							if(this.assistNodeIsClass) {
								if(!typeBinding.isClass()) continue;
							} else if(this.assistNodeIsInterface) {
								if(!typeBinding.isInterface() && !typeBinding.isAnnotationType()) continue;
							} else if (this.assistNodeIsAnnotation) {
								if(!typeBinding.isAnnotationType()) continue;
							}

							int relevance = computeBaseRelevance();
							relevance += computeRelevanceForResolution();
							relevance += computeRelevanceForInterestingProposal();
							relevance += computeRelevanceForCaseMatching(token, typeBinding.sourceName);
							relevance += computeRelevanceForExpectingType(typeBinding);
							relevance += computeRelevanceForQualification(false);
							relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);

							if (typeBinding.isClass()) {
								relevance += computeRelevanceForClass();
								relevance += computeRelevanceForException(typeBinding.sourceName);
							} else if(typeBinding.isEnum()) {
								relevance += computeRelevanceForEnum();
							} else if(typeBinding.isInterface()) {
								relevance += computeRelevanceForInterface();
							}

							this.noProposal = false;
							if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
								InternalCompletionProposal proposal =  createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
								proposal.setDeclarationSignature(typeBinding.qualifiedPackageName());
								proposal.setSignature(getSignature(typeBinding));
								proposal.setPackageName(typeBinding.qualifiedPackageName());
								proposal.setTypeName(typeBinding.qualifiedSourceName());
								proposal.setCompletion(typeBinding.sourceName());
								proposal.setFlags(typeBinding.modifiers);
								proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
								proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
								proposal.setRelevance(relevance);
								this.requestor.accept(proposal);
								if(DEBUG) {
									this.printDebug(proposal);
								}
							}
						}
					}
				}
			}
		}
	}

	private void findUnresolvedReference(int completedNameStart, int completedNameEnd, BlockScope scope, char[][] discouragedNames) {
		char[][] foundNames = findUnresolvedReferenceBefore(completedNameStart - 1, completedNameEnd, scope, discouragedNames);
		if (foundNames != null && foundNames.length > 1) {
			int discouragedNamesLength = discouragedNames.length;
			int foundNamesLength = foundNames.length;
			int newLength = discouragedNamesLength + foundNamesLength;
			System.arraycopy(discouragedNames, 0, discouragedNames = new char[newLength][], 0, discouragedNamesLength);
			System.arraycopy(foundNames, 0, discouragedNames, discouragedNamesLength, foundNamesLength);
		}
		findUnresolvedReferenceAfter(completedNameEnd + 1, scope, discouragedNames);
	}

	private char[][] findUnresolvedReferenceAfter(int from, BlockScope scope, final char[][] discouragedNames) {
		final ArrayList proposedNames = new ArrayList();

		UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor nameRequestor =
			new UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor() {
				public void acceptName(char[] name) {
					CompletionEngine.this.acceptUnresolvedName(name);
					proposedNames.add(name);
				}
			};

		ReferenceContext referenceContext = scope.referenceContext();
		if (referenceContext instanceof AbstractMethodDeclaration) {
			AbstractMethodDeclaration md = (AbstractMethodDeclaration)referenceContext;

			UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
			nameFinder.findAfter(
					this.completionToken,
					md.scope,
					md.scope.classScope(),
					from,
					md.bodyEnd,
					discouragedNames,
					nameRequestor);
		} else if (referenceContext instanceof TypeDeclaration) {
			TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext;
			FieldDeclaration[] fields = typeDeclaration.fields;
			if (fields != null) {
				done : for (int i = 0; i < fields.length; i++) {
					if (fields[i] instanceof Initializer) {
						Initializer initializer = (Initializer) fields[i];
						if (initializer.block.sourceStart <= from &&
								from < initializer.bodyEnd) {
							UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
							nameFinder.findAfter(
										this.completionToken,
										typeDeclaration.scope,
										typeDeclaration.scope,
										from,
										initializer.bodyEnd,
										discouragedNames,
										nameRequestor);
							break done;
						}
					}
				}
			}
		}

		int proposedNamesCount = proposedNames.size();
		if (proposedNamesCount > 0) {
			return (char[][])proposedNames.toArray(new char[proposedNamesCount][]);
		}

		return null;
	}

	private char[][] findUnresolvedReferenceBefore(int recordTo, int parseTo, BlockScope scope, final char[][] discouragedNames) {
		final ArrayList proposedNames = new ArrayList();

		UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor nameRequestor =
			new UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor() {
				public void acceptName(char[] name) {
					CompletionEngine.this.acceptUnresolvedName(name);
					proposedNames.add(name);
				}
			};

		BlockScope upperScope = scope;
		while (upperScope.enclosingMethodScope() != null) {
			upperScope = upperScope.enclosingMethodScope();
		}

		ReferenceContext referenceContext = upperScope.referenceContext();
		if (referenceContext instanceof AbstractMethodDeclaration) {
			AbstractMethodDeclaration md = (AbstractMethodDeclaration)referenceContext;

			UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
			nameFinder.findBefore(
					this.completionToken,
					md.scope,
					md.scope.classScope(),
					md.bodyStart,
					recordTo,
					parseTo,
					discouragedNames,
					nameRequestor);
		} else if (referenceContext instanceof TypeDeclaration) {
			TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext;


			done : {
				FieldDeclaration[] fields = typeDeclaration.fields;
				if (fields != null) {
					for (int i = 0; i < fields.length; i++) {
						if (fields[i] instanceof Initializer) {
							Initializer initializer = (Initializer) fields[i];
							if (initializer.block.sourceStart <= recordTo &&
									recordTo < initializer.bodyEnd) {

								UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
								nameFinder.findBefore(
										this.completionToken,
										typeDeclaration.scope,
										typeDeclaration.scope,
										initializer.block.sourceStart,
										recordTo,
										parseTo,
										discouragedNames,
										nameRequestor);
								break done;
							}
						}
					}
				}
			}
		}

		int proposedNamesCount = proposedNames.size();
		if (proposedNamesCount > 0) {
			return (char[][])proposedNames.toArray(new char[proposedNamesCount][]);
		}

		return null;
	}

	private char[][] findVariableFromUnresolvedReference(LocalDeclaration variable, BlockScope scope, final char[][] discouragedNames) {
		final TypeReference type = variable.type;
		if(type != null &&
				type.resolvedType != null &&
				type.resolvedType.problemId() == ProblemReasons.NoError){

			final ArrayList proposedNames = new ArrayList();

			UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor nameRequestor =
				new UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor() {
					public void acceptName(char[] name) {
						int relevance = computeBaseRelevance();
						relevance += computeRelevanceForInterestingProposal();
						relevance += computeRelevanceForCaseMatching(CompletionEngine.this.completionToken, name);
						relevance += R_NAME_FIRST_PREFIX;
						relevance += R_NAME_FIRST_SUFFIX;
						relevance += R_NAME_LESS_NEW_CHARACTERS;
						relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for variable name

						// accept result
						CompletionEngine.this.noProposal = false;
						if(!CompletionEngine.this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
							InternalCompletionProposal proposal =  CompletionEngine.this.createProposal(CompletionProposal.VARIABLE_DECLARATION, CompletionEngine.this.actualCompletionPosition);
							proposal.setSignature(getSignature(type.resolvedType));
							proposal.setPackageName(type.resolvedType.qualifiedPackageName());
							proposal.setTypeName(type.resolvedType.qualifiedSourceName());
							proposal.setName(name);
							proposal.setCompletion(name);
							//proposal.setFlags(Flags.AccDefault);
							proposal.setReplaceRange(CompletionEngine.this.startPosition - CompletionEngine.this.offset, CompletionEngine.this.endPosition - CompletionEngine.this.offset);
							proposal.setTokenRange(CompletionEngine.this.tokenStart - CompletionEngine.this.offset, CompletionEngine.this.tokenEnd - CompletionEngine.this.offset);
							proposal.setRelevance(relevance);
							CompletionEngine.this.requestor.accept(proposal);
							if(DEBUG) {
								CompletionEngine.this.printDebug(proposal);
							}
						}
						proposedNames.add(name);
					}
				};

			ReferenceContext referenceContext = scope.referenceContext();
			if (referenceContext instanceof AbstractMethodDeclaration) {
				AbstractMethodDeclaration md = (AbstractMethodDeclaration)referenceContext;

				UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
				nameFinder.find(
						this.completionToken,
						md,
						variable.declarationSourceEnd + 1,
						discouragedNames,
						nameRequestor);
			} else if (referenceContext instanceof TypeDeclaration) {
				TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext;
				FieldDeclaration[] fields = typeDeclaration.fields;
				if (fields != null) {
					done : for (int i = 0; i < fields.length; i++) {
						if (fields[i] instanceof Initializer) {
							Initializer initializer = (Initializer) fields[i];
							if (initializer.bodyStart <= variable.sourceStart &&
									variable.sourceStart < initializer.bodyEnd) {
								UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
								nameFinder.find(
										this.completionToken,
										initializer,
										typeDeclaration.scope,
										variable.declarationSourceEnd + 1,
										discouragedNames,
										nameRequestor);
								break done;
							}
						}
					}
				}
			}

			int proposedNamesCount = proposedNames.size();
			if (proposedNamesCount > 0) {
				return (char[][])proposedNames.toArray(new char[proposedNamesCount][]);
			}
		}

		return null;
	}

	private void findVariableName(
			char[] token,
			char[] qualifiedPackageName,
			char[] qualifiedSourceName,
			char[] sourceName,
			final TypeBinding typeBinding,
			char[][] discouragedNames,
			final char[][] forbiddenNames,
			boolean forCollection,
			int dim,
			int kind){

		if(sourceName == null || sourceName.length == 0)
			return;

		// compute variable name for non base type
		final char[] displayName;
		if (!forCollection) {
			if (dim > 0){
				int l = qualifiedSourceName.length;
				displayName = new char[l+(2*dim)];
				System.arraycopy(qualifiedSourceName, 0, displayName, 0, l);
				for(int i = 0; i < dim; i++){
					displayName[l+(i*2)] = '[';
					displayName[l+(i*2)+1] = ']';
				}
			} else {
				displayName = qualifiedSourceName;
			}
		} else {
			displayName = typeBinding.qualifiedSourceName();
		}

		final char[] t = token;
		final char[] q = qualifiedPackageName;
		INamingRequestor namingRequestor = new INamingRequestor() {
			void accept(char[] name, int prefixAndSuffixRelevance, int reusedCharacters){
				int l = forbiddenNames == null ? 0 : forbiddenNames.length;
				for (int i = 0; i < l; i++) {
					if (CharOperation.equals(forbiddenNames[i], name, false)) return;
				}

				if (CharOperation.prefixEquals(t, name, false)) {
					int relevance = computeBaseRelevance();
					relevance += computeRelevanceForInterestingProposal();
					relevance += computeRelevanceForCaseMatching(t, name);
					relevance += prefixAndSuffixRelevance;
					if(reusedCharacters > 0) relevance += R_NAME_LESS_NEW_CHARACTERS;
					relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for variable name

					// accept result
					CompletionEngine.this.noProposal = false;
					if(!CompletionEngine.this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
						InternalCompletionProposal proposal =  CompletionEngine.this.createProposal(CompletionProposal.VARIABLE_DECLARATION, CompletionEngine.this.actualCompletionPosition);
						proposal.setSignature(getSignature(typeBinding));
						proposal.setPackageName(q);
						proposal.setTypeName(displayName);
						proposal.setName(name);
						proposal.setCompletion(name);
						//proposal.setFlags(Flags.AccDefault);
						proposal.setReplaceRange(CompletionEngine.this.startPosition - CompletionEngine.this.offset, CompletionEngine.this.endPosition - CompletionEngine.this.offset);
						proposal.setTokenRange(CompletionEngine.this.tokenStart - CompletionEngine.this.offset, CompletionEngine.this.tokenEnd - CompletionEngine.this.offset);
						proposal.setRelevance(relevance);
						CompletionEngine.this.requestor.accept(proposal);
						if(DEBUG) {
							CompletionEngine.this.printDebug(proposal);
						}
					}
				}
			}

			public void acceptNameWithoutPrefixAndSuffix(char[] name,int reusedCharacters) {
				accept(name, 0, reusedCharacters);
			}

			public void acceptNameWithPrefix(char[] name, boolean isFirstPrefix, int reusedCharacters) {
				accept(name, isFirstPrefix ? R_NAME_FIRST_PREFIX :  R_NAME_PREFIX, reusedCharacters);
			}

			public void acceptNameWithPrefixAndSuffix(char[] name, boolean isFirstPrefix, boolean isFirstSuffix, int reusedCharacters) {
				accept(
						name,
						(isFirstPrefix ? R_NAME_FIRST_PREFIX : R_NAME_PREFIX) + (isFirstSuffix ? R_NAME_FIRST_SUFFIX : R_NAME_SUFFIX),
						reusedCharacters);
			}
			public void acceptNameWithSuffix(char[] name, boolean isFirstSuffix, int reusedCharacters) {
				accept(name, isFirstSuffix ? R_NAME_FIRST_SUFFIX : R_NAME_SUFFIX, reusedCharacters);
			}
		};

		InternalNamingConventions.suggestVariableNames(
				kind,
				InternalNamingConventions.BK_SIMPLE_TYPE_NAME,
				qualifiedSourceName,
				this.javaProject,
				dim,
				token,
				discouragedNames,
				true,
				namingRequestor);
	}

	// Helper method for private void findVariableNames(char[] name, TypeReference type )
	private void findVariableName(
			char[] token,
			char[] qualifiedPackageName,
			char[] qualifiedSourceName,
			char[] sourceName,
			final TypeBinding typeBinding,
			char[][] discouragedNames,
			final char[][] forbiddenNames,
			int dim,
			int kind){
		findVariableName(
				token,
				qualifiedPackageName,
				qualifiedSourceName,
				sourceName,
				typeBinding,
				discouragedNames,
				forbiddenNames,
				false,
				dim,
				kind);
	}
	private void findVariableNameForCollection(
			char[] token,
			char[] qualifiedPackageName,
			char[] qualifiedSourceName,
			char[] sourceName,
			final TypeBinding typeBinding,
			char[][] discouragedNames,
			final char[][] forbiddenNames,
			int kind){

		findVariableName(
				token,
				qualifiedPackageName,
				qualifiedSourceName,
				sourceName,
				typeBinding,
				discouragedNames,
				forbiddenNames,
				false,
				1,
				kind);
	}
	private void findVariableNames(char[] name, TypeReference type , char[][] discouragedNames, char[][] forbiddenNames, int kind){
		if(type != null &&
			type.resolvedType != null) {
			TypeBinding tb = type.resolvedType;

			if (tb.problemId() == ProblemReasons.NoError &&
					tb != Scope.getBaseType(VOID)) {
				findVariableName(
					name,
					tb.leafComponentType().qualifiedPackageName(),
					tb.leafComponentType().qualifiedSourceName(),
					tb.leafComponentType().sourceName(),
					tb,
					discouragedNames,
					forbiddenNames,
					type.dimensions(),
					kind);
				
				if (tb.isParameterizedType() &&
						tb.findSuperTypeOriginatingFrom(TypeIds.T_JavaUtilCollection, false) != null) {
					ParameterizedTypeBinding ptb = ((ParameterizedTypeBinding) tb);
					TypeBinding[] arguments = ptb.arguments;
					if (arguments != null && arguments.length == 1) {
						TypeBinding argument = arguments[0];
						findVariableNameForCollection(
							name,
							argument.leafComponentType().qualifiedPackageName(),
							argument.leafComponentType().qualifiedSourceName(),
							argument.leafComponentType().sourceName(),
							tb,
							discouragedNames,
							forbiddenNames,
							kind);
					}
				}
			}
		}

	}
	private void findVariablesAndMethods(
		char[] token,
		Scope scope,
		InvocationSite invocationSite,
		Scope invocationScope,
		boolean insideTypeAnnotation,
		boolean insideAnnotationAttribute) {

		if (token == null)
			return;

		// Should local variables hide fields from the receiver type or any of its enclosing types?
		// we know its an implicit field/method access... see BlockScope getBinding/getImplicitMethod

		boolean staticsOnly = false;
		// need to know if we're in a static context (or inside a constructor)
		int tokenLength = token.length;

		ObjectVector localsFound = new ObjectVector();
		ObjectVector fieldsFound = new ObjectVector();
		ObjectVector methodsFound = new ObjectVector();

		Scope currentScope = scope;

		if (!this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
			done1 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found

				switch (currentScope.kind) {

					case Scope.METHOD_SCOPE :
						// handle the error case inside an explicit constructor call (see MethodScope>>findField)
						MethodScope methodScope = (MethodScope) currentScope;
						staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;

					//$FALL-THROUGH$
					case Scope.BLOCK_SCOPE :
						BlockScope blockScope = (BlockScope) currentScope;

						next : for (int i = 0, length = blockScope.locals.length; i < length; i++) {
							LocalVariableBinding local = blockScope.locals[i];

							if (local == null)
								break next;

							if (tokenLength > local.name.length)
								continue next;

							if (!CharOperation.prefixEquals(token, local.name, false /* ignore case */)
									&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, local.name)))
								continue next;

							if (local.isSecret())
								continue next;
												
							// don't propose array types in case expression
							// https://bugs.eclipse.org/bugs/show_bug.cgi?id=195346
							if (this.assistNodeIsInsideCase && local.type instanceof ArrayBinding)
								continue next;
							
							int ptr = this.uninterestingBindingsPtr;
							// Cases where the binding is uninteresting eg. for completion occurring inside a local var
							// declaration, the local var binding is uninteresting and shouldn't be proposed.
							while (ptr >= 0) {
								if (this.uninterestingBindings[ptr] == local) {
									continue next;
								}
								ptr--;
							}

							for (int f = 0; f < localsFound.size; f++) {
								LocalVariableBinding otherLocal =
									(LocalVariableBinding) localsFound.elementAt(f);
								if (CharOperation.equals(otherLocal.name, local.name, true))
									continue next;
							}
							localsFound.add(local);

							int relevance = computeBaseRelevance();
							relevance += computeRelevanceForResolution();
							relevance += computeRelevanceForInterestingProposal(local);
							relevance += computeRelevanceForCaseMatching(token, local.name);
							relevance += computeRelevanceForExpectingType(local.type);
							relevance += computeRelevanceForEnumConstant(local.type);
							relevance += computeRelevanceForQualification(false);
							relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for local variable
							relevance += computeRelevanceForFinal(this.assistNodeIsInsideCase, local.isFinal());
							this.noProposal = false;
							if(!this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
								InternalCompletionProposal proposal =  createProposal(CompletionProposal.LOCAL_VARIABLE_REF, this.actualCompletionPosition);
								proposal.setSignature(
									local.type == null
									? createTypeSignature(
											CharOperation.NO_CHAR,
											local.declaration.type.toString().toCharArray())
									: getSignature(local.type));
								if(local.type == null) {
									//proposal.setPackageName(null);
									proposal.setTypeName(local.declaration.type.toString().toCharArray());
								} else {
									proposal.setPackageName(local.type.qualifiedPackageName());
									proposal.setTypeName(local.type.qualifiedSourceName());
								}
								proposal.setName(local.name);
								proposal.setCompletion(local.name);
								proposal.setFlags(local.modifiers);
								proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
								proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
								proposal.setRelevance(relevance);
								this.requestor.accept(proposal);
								if(DEBUG) {
									this.printDebug(proposal);
								}
							}
						}
						break;

					case Scope.COMPILATION_UNIT_SCOPE :
						break done1;
				}
				currentScope = currentScope.parent;
			}
		}
		
		checkCancel();

		boolean proposeField = !this.requestor.isIgnored(CompletionProposal.FIELD_REF);
		boolean proposeMethod = !this.requestor.isIgnored(CompletionProposal.METHOD_REF);

		staticsOnly = false;
		currentScope = scope;

		if(proposeField || proposeMethod) {
			done2 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found

				switch (currentScope.kind) {
					case Scope.METHOD_SCOPE :
						// handle the error case inside an explicit constructor call (see MethodScope>>findField)
						MethodScope methodScope = (MethodScope) currentScope;
						staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
						break;
					case Scope.CLASS_SCOPE :
						ClassScope classScope = (ClassScope) currentScope;
						SourceTypeBinding enclosingType = classScope.referenceContext.binding;
						/*				if (tokenLength == 0) { // only search inside the type itself if no prefix was provided
											findFields(token, enclosingType.fields(), classScope, fieldsFound, staticsOnly);
											findMethods(token, enclosingType.methods(), classScope, methodsFound, staticsOnly, false);
											break done;
										} else { */
						if(!insideTypeAnnotation) {
							if(proposeField) {
								findFields(
									token,
									enclosingType,
									classScope,
									fieldsFound,
									localsFound,
									staticsOnly,
									invocationSite,
									invocationScope,
									true,
									true,
									null,
									null,
									null,
									false,
									null,
									-1,
									-1);
							}
							if(proposeMethod && !insideAnnotationAttribute) {
								findMethods(
									token,
									null,
									null,
									enclosingType,
									classScope,
									methodsFound,
									staticsOnly,
									false,
									invocationSite,
									invocationScope,
									true,
									false,
									true,
									null,
									null,
									null,
									false,
									null,
									-1,
									-1);
							}
						}
						staticsOnly |= enclosingType.isStatic();
						insideTypeAnnotation = false;
						//				}
						break;

					case Scope.COMPILATION_UNIT_SCOPE :
						break done2;
				}
				currentScope = currentScope.parent;
			}
			
			checkCancel();
			
			findFieldsAndMethodsFromStaticImports(
					token,
					scope,
					invocationSite,
					invocationScope,
					false,
					insideAnnotationAttribute,
					localsFound,
					fieldsFound,
					methodsFound,
					proposeField,
					proposeMethod);

			if (this.assistNodeInJavadoc == 0) {
				
				checkCancel();
				
				// search in favorites import
				findFieldsAndMethodsFromFavorites(
						token,
						scope,
						invocationSite,
						invocationScope,
						localsFound,
						fieldsFound,
						methodsFound);
			}
			
			checkCancel();
			
			findEnumConstantsFromExpectedTypes(
					token,
					invocationScope,
					fieldsFound);
		}
	}

	private char[] getCompletedTypeSignature(ReferenceBinding referenceBinding) {
		char[] result = null;
		StringBuffer sig = new StringBuffer(10);
		if (!referenceBinding.isMemberType()) {
			char[] typeSig = referenceBinding.genericTypeSignature();
			sig.append(typeSig, 0, typeSig.length);
		} else if (!this.insideQualifiedReference) {
			if (referenceBinding.isStatic()) {
				char[] typeSig = referenceBinding.signature();
				sig.append(typeSig, 0, typeSig.length-1); // copy all but trailing semicolon

				TypeVariableBinding[] typeVariables = referenceBinding.typeVariables();
				if (typeVariables != Binding.NO_TYPE_VARIABLES) {
				    sig.append(Signature.C_GENERIC_START);
				    for (int i = 0, length = typeVariables.length; i < length; i++) {
				        sig.append(typeVariables[i].genericTypeSignature());
				    }
				    sig.append(Signature.C_GENERIC_END);
				}
				sig.append(Signature.C_SEMICOLON);
			} else {
				char[] typeSig = referenceBinding.genericTypeSignature();
				sig.append(typeSig, 0, typeSig.length);
			}
		} else {
			ReferenceBinding enclosingType = referenceBinding.enclosingType();
			if (enclosingType.isParameterizedType()) {
				char[] typeSig = referenceBinding.genericTypeSignature();
				sig.append(typeSig, 0, typeSig.length-1);

				TypeVariableBinding[] typeVariables = referenceBinding.typeVariables();
				if (typeVariables != Binding.NO_TYPE_VARIABLES) {
				    sig.append(Signature.C_GENERIC_START);
				    for (int i = 0, length = typeVariables.length; i < length; i++) {
				        sig.append(typeVariables[i].genericTypeSignature());
				    }
				    sig.append(Signature.C_GENERIC_END);
				}
			} else {
				char[] typeSig = referenceBinding.signature();
				sig.append(typeSig, 0, typeSig.length-1); // copy all but trailing semicolon

				if (referenceBinding.isStatic()) {
					TypeVariableBinding[] typeVariables = referenceBinding.typeVariables();
					if (typeVariables != Binding.NO_TYPE_VARIABLES) {
					    sig.append(Signature.C_GENERIC_START);
					    for (int i = 0, length = typeVariables.length; i < length; i++) {
					        sig.append(typeVariables[i].genericTypeSignature());
					    }
					    sig.append(Signature.C_GENERIC_END);
					}
				}
			}
			sig.append(Signature.C_SEMICOLON);
		}
		int sigLength = sig.length();
		result = new char[sigLength];
		sig.getChars(0, sigLength, result, 0);
		result = CharOperation.replaceOnCopy(result, '/', Signature.C_DOT);
		return result;
	}

	private ImportBinding[] getFavoriteReferenceBindings(Scope scope) {
		if (this.favoriteReferenceBindings != null) return this.favoriteReferenceBindings;

		String[] favoriteReferences = this.requestor.getFavoriteReferences();

		if (favoriteReferences == null || favoriteReferences.length == 0) return null;

		ImportBinding[] resolvedImports = new ImportBinding[favoriteReferences.length];

		int count = 0;
		next : for (int i = 0; i < favoriteReferences.length; i++) {
			String favoriteReference = favoriteReferences[i];

			int length;
			if (favoriteReference == null || (length = favoriteReference.length()) == 0) continue next;

			boolean onDemand = favoriteReference.charAt(length - 1) == '*';

			char[][] compoundName = CharOperation.splitOn('.', favoriteReference.toCharArray());
			if (onDemand) {
				compoundName = CharOperation.subarray(compoundName, 0, compoundName.length - 1);
			}

			// remove duplicate and conflicting
			for (int j = 0; j < count; j++) {
				ImportReference f = resolvedImports[j].reference;

				if (CharOperation.equals(f.tokens, compoundName)) continue next;

				if (!onDemand && ((f.bits & ASTNode.OnDemand) == 0)) {
					if (CharOperation.equals(f.tokens[f.tokens.length - 1], compoundName[compoundName.length - 1]))
						continue next;
				}
			}

			boolean isStatic = true;

			ImportReference importReference =
				new ImportReference(
						compoundName,
						new long[compoundName.length],
						onDemand,
						isStatic ? ClassFileConstants.AccStatic : ClassFileConstants.AccDefault);

			Binding importBinding = this.unitScope.findImport(compoundName, isStatic, onDemand);

			if (!importBinding.isValidBinding()) {
				continue next;
			}

			if (importBinding instanceof PackageBinding) {
				continue next;
			}

			resolvedImports[count++] =
				new ImportBinding(compoundName, onDemand, importBinding, importReference);
		}

		if (resolvedImports.length > count)
			System.arraycopy(resolvedImports, 0, resolvedImports = new ImportBinding[count], 0, count);

		return this.favoriteReferenceBindings = resolvedImports;
	}
	
	private INameEnvironment getNoCacheNameEnvironment() {
		if (this.noCacheNameEnvironment == null) {
			JavaModelManager.getJavaModelManager().cacheZipFiles(this);
			this.noCacheNameEnvironment = new JavaSearchNameEnvironment(this.javaProject, this.owner == null ? null : JavaModelManager.getJavaModelManager().getWorkingCopies(this.owner, true/*add primary WCs*/));
		}
		return this.noCacheNameEnvironment;
	}

	public AssistParser getParser() {

		return this.parser;
	}
	protected boolean hasArrayTypeAsExpectedSuperTypes() {
		if ((this.expectedTypesFilter & ~SUBTYPE) != 0) return false;
		
		if (!this.hasComputedExpectedArrayTypes) {
			if(this.expectedTypes != null) {
				done : for (int i = 0; i <= this.expectedTypesPtr; i++) {
					if(this.expectedTypes[i].isArrayType()) {
						this.hasExpectedArrayTypes = true;
						break done;
					}
				}
			}
			
			this.hasComputedExpectedArrayTypes = true;
		}
		
		return this.hasExpectedArrayTypes;
	}
	protected boolean hasPossibleAnnotationTarget(TypeBinding typeBinding, Scope scope) {
		if (this.targetedElement == TagBits.AnnotationForPackage) {
			long target = typeBinding.getAnnotationTagBits() & TagBits.AnnotationTargetMASK;
			if(target != 0 && (target & TagBits.AnnotationForPackage) == 0) {
				return false;
			}
		} else if ((this.targetedElement & TagBits.AnnotationForType) != 0) {
			if (scope.parent != null &&
					scope.parent.parent != null &&
					scope.parent.referenceContext() instanceof CompletionOnAnnotationOfType &&
					scope.parent.parent instanceof CompilationUnitScope) {
				long target = typeBinding.getAnnotationTagBits() & TagBits.AnnotationTargetMASK;
				if ((this.targetedElement & TagBits.AnnotationForAnnotationType) != 0) {
					if(target != 0 && (target &(TagBits.AnnotationForType | TagBits.AnnotationForAnnotationType)) == 0) {
						return false;
					}
				} else {
					if(target != 0 && (target &(TagBits.AnnotationForType)) == 0) {
						return false;
					}
				}
			}
		}
		return true;
	}
	/**
	 * Returns completion string inserted inside a specified inline tag.
	 * @param completionName
	 * @return char[] Completion text inclunding specified inline tag
	 */
	private char[] inlineTagCompletion(char[] completionName, char[] inlineTag) {
		int tagLength= inlineTag.length;
		int completionLength = completionName.length;
		int inlineLength = 2+tagLength+1+completionLength+1;
		char[] inlineCompletion = new char[inlineLength];
		inlineCompletion[0] = '{';
		inlineCompletion[1] = '@';
		System.arraycopy(inlineTag, 0, inlineCompletion, 2, tagLength);
		inlineCompletion[tagLength+2] = ' ';
		System.arraycopy(completionName, 0, inlineCompletion, tagLength+3, completionLength);
		// do not add space at end of inline tag (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=121026)
		//inlineCompletion[inlineLength-2] = ' ';
		inlineCompletion[inlineLength-1] = '}';
		return inlineCompletion;
	}
	private boolean isAllowingLongComputationProposals() {
		return this.monitor != null;
	}
	private boolean isForbidden(Binding binding) {
		for (int i = 0; i <= this.forbbidenBindingsPtr; i++) {
			if(this.forbbidenBindings[i] == binding) {
				return true;
			}
			if((this.forbbidenBindingsFilter & SUBTYPE) != 0) {
				if (binding instanceof TypeBinding &&
						this.forbbidenBindings[i] instanceof TypeBinding &&
						((TypeBinding)binding).isCompatibleWith((TypeBinding)this.forbbidenBindings[i])) {
					return true;
				}
			}
		}
		return false;
	}

	private boolean isForbiddenType(char[] givenPkgName, char[] givenTypeName, char[][] enclosingTypeNames) {
		// CharOperation.concatWith() handles the cases where input args are null/empty
		char[] fullTypeName = CharOperation.concatWith(enclosingTypeNames, givenTypeName, '.');
		for (int i = 0; i <= this.forbbidenBindingsPtr; i++) {
			if (this.forbbidenBindings[i] instanceof TypeBinding) {
				TypeBinding typeBinding = (TypeBinding) this.forbbidenBindings[i];
				char[] currPkgName = typeBinding.qualifiedPackageName();
				if (CharOperation.equals(givenPkgName, currPkgName))	{
					char[] currTypeName = typeBinding.qualifiedSourceName();
					if (CharOperation.equals(fullTypeName, currTypeName)) {
						return true;
					}
				}
			}
		}
		return false;
	}

	private boolean isIgnored(int kind) {
		return this.requestor.isIgnored(kind);
	}
	boolean isIgnored(int kind, boolean missingTypes) {
		return this.requestor.isIgnored(kind) ||
			(missingTypes && !this.requestor.isAllowingRequiredProposals(kind, CompletionProposal.TYPE_REF));
	}

	private boolean isIgnored(int kind, int requiredProposalKind) {
		return this.requestor.isIgnored(kind) ||
			!this.requestor.isAllowingRequiredProposals(kind, requiredProposalKind);
	}
	private boolean isValidParent(ASTNode parent, ASTNode node, Scope scope){

		if(parent instanceof ParameterizedSingleTypeReference) {
			ParameterizedSingleTypeReference ref = (ParameterizedSingleTypeReference) parent;
			TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables();
			int length = ref.typeArguments == null ? 0 : ref.typeArguments.length;
			int nodeIndex = -1;
			for(int i = length - 1 ; i > -1 ; i--) {
				if(node == ref.typeArguments[i]) {
					nodeIndex = i;
					break;
				}
			}
			if(nodeIndex > -1 && (typeVariables == null || typeVariables.length < nodeIndex + 1)) {
				TypeBinding[] typeBindings = new TypeBinding[nodeIndex + 1];
				for(int i = 0; i < nodeIndex; i++) {
					typeBindings[i] = ref.typeArguments[i].resolvedType;
				}
				typeBindings[nodeIndex] = scope.getJavaLangObject();
				if(typeVariables == null || typeVariables.length == 0) {
					scope.problemReporter().nonGenericTypeCannotBeParameterized(0, ref, ref.resolvedType, typeBindings);
				} else {
					scope.problemReporter().incorrectArityForParameterizedType(ref, ref.resolvedType, typeBindings);
				}
				return false;
			}
		} else if(parent instanceof ParameterizedQualifiedTypeReference) {
			ParameterizedQualifiedTypeReference ref = (ParameterizedQualifiedTypeReference) parent;
			TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables();
			TypeReference[][] arguments = ref.typeArguments;
			int iLength = arguments == null ? 0 : arguments.length;
			for (int i = 0; i < iLength; i++) {
				int jLength = arguments[i] == null ? 0 : arguments[i].length;
				for (int j = 0; j < jLength; j++) {
					if(arguments[i][j] == node && (typeVariables == null || typeVariables.length <= j)) {
						TypeBinding[] typeBindings = new TypeBinding[j + 1];
						for(int k = 0; k < j; k++) {
							typeBindings[k] = ref.typeArguments[i][k].resolvedType;
						}
						typeBindings[j] = scope.getJavaLangObject();
						if(typeVariables == null || typeVariables.length == 0) {
							scope.problemReporter().nonGenericTypeCannotBeParameterized(0, ref, ref.resolvedType, typeBindings);
						} else {
							scope.problemReporter().incorrectArityForParameterizedType(ref, ref.resolvedType, typeBindings);
						}
						return false;
					}
				}
			}
		}
		return true;
	}
	private boolean mustQualifyType(ReferenceBinding type, char[] packageName, Scope scope) {
		if(!mustQualifyType(
				packageName,
				type.sourceName(),
				type.isMemberType() ? type.enclosingType().qualifiedSourceName() : null,
				type.modifiers)) {
			return false;
		}
		ReferenceBinding enclosingType = scope.enclosingSourceType();
		while (enclosingType != null) {
			ReferenceBinding currentType = enclosingType;
			while (currentType != null) {
				ReferenceBinding[] memberTypes = currentType.memberTypes();
				if(memberTypes != null) {
					for (int i = 0; i < memberTypes.length; i++) {
						if (CharOperation.equals(memberTypes[i].sourceName, type.sourceName()) &&
								memberTypes[i].canBeSeenBy(scope)) {
							return memberTypes[i] != type;
						}
					}
				}
				currentType = currentType.superclass();
			}
			enclosingType = enclosingType.enclosingType();
		}
		return true;
	}
	private Initializer parseSnippeInitializer(char[] snippet, int position, char[][] localVariableTypeNames, char[][] localVariableNames, int[] localVariableModifiers, boolean isStatic){
		StringBuffer prefix = new StringBuffer();
		prefix.append("public class FakeType {\n "); //$NON-NLS-1$
		if(isStatic) {
			prefix.append("static "); //$NON-NLS-1$
		}
		prefix.append("{\n"); //$NON-NLS-1$
		for (int i = 0; i < localVariableTypeNames.length; i++) {
			ASTNode.printModifiers(localVariableModifiers[i], prefix);
			prefix.append(' ');
			prefix.append(localVariableTypeNames[i]);
			prefix.append(' ');
			prefix.append(localVariableNames[i]);
			prefix.append(';');
		}

		char[] fakeSource = CharOperation.concat(prefix.toString().toCharArray(), snippet, "}}".toCharArray());//$NON-NLS-1$
		this.offset = prefix.length();

		String encoding = this.compilerOptions.defaultEncoding;
		BasicCompilationUnit fakeUnit = new BasicCompilationUnit(
			fakeSource,
			null,
			"FakeType.java", //$NON-NLS-1$
			encoding);

		this.actualCompletionPosition = prefix.length() + position - 1;

		CompilationResult fakeResult = new CompilationResult(fakeUnit, 1, 1, this.compilerOptions.maxProblemsPerUnit);
		CompilationUnitDeclaration fakeAST = this.parser.dietParse(fakeUnit, fakeResult, this.actualCompletionPosition);

		parseBlockStatements(fakeAST, this.actualCompletionPosition);

		return (Initializer)fakeAST.types[0].fields[0];
	}
	protected void printDebug(CategorizedProblem error) {
		if(CompletionEngine.DEBUG) {
			System.out.print("COMPLETION - completionFailure("); //$NON-NLS-1$
			System.out.print(error);
			System.out.println(")"); //$NON-NLS-1$
		}
	}
	protected void printDebug(CompletionProposal proposal){
		StringBuffer buffer = new StringBuffer();
		printDebug(proposal, 0, buffer);
		System.out.println(buffer.toString());
	}

	private void printDebug(CompletionProposal proposal, int tab, StringBuffer buffer){
		printDebugTab(tab, buffer);
		buffer.append("COMPLETION - "); //$NON-NLS-1$
		switch(proposal.getKind()) {
			case CompletionProposal.ANONYMOUS_CLASS_DECLARATION :
				buffer.append("ANONYMOUS_CLASS_DECLARATION"); //$NON-NLS-1$
				break;
			case CompletionProposal.FIELD_REF :
				buffer.append("FIELD_REF"); //$NON-NLS-1$
				break;
			case CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER :
				buffer.append("FIELD_REF_WITH_CASTED_RECEIVER"); //$NON-NLS-1$
				break;
			case CompletionProposal.KEYWORD :
				buffer.append("KEYWORD"); //$NON-NLS-1$
				break;
			case CompletionProposal.LABEL_REF :
				buffer.append("LABEL_REF"); //$NON-NLS-1$
				break;
			case CompletionProposal.LOCAL_VARIABLE_REF :
				buffer.append("LOCAL_VARIABLE_REF"); //$NON-NLS-1$
				break;
			case CompletionProposal.METHOD_DECLARATION :
				buffer.append("METHOD_DECLARATION"); //$NON-NLS-1$
				break;
			case CompletionProposal.METHOD_REF :
				buffer.append("METHOD_REF"); //$NON-NLS-1$
				break;
			case CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER :
				buffer.append("METHOD_REF_WITH_CASTED_RECEIVER"); //$NON-NLS-1$
				break;
			case CompletionProposal.PACKAGE_REF :
				buffer.append("PACKAGE_REF"); //$NON-NLS-1$
				break;
			case CompletionProposal.TYPE_REF :
				buffer.append("TYPE_REF"); //$NON-NLS-1$
				break;
			case CompletionProposal.VARIABLE_DECLARATION :
				buffer.append("VARIABLE_DECLARATION"); //$NON-NLS-1$
				break;
			case CompletionProposal.POTENTIAL_METHOD_DECLARATION :
				buffer.append("POTENTIAL_METHOD_DECLARATION"); //$NON-NLS-1$
				break;
			case CompletionProposal.METHOD_NAME_REFERENCE :
				buffer.append("METHOD_NAME_REFERENCE"); //$NON-NLS-1$
				break;
			case CompletionProposal.ANNOTATION_ATTRIBUTE_REF :
				buffer.append("ANNOTATION_ATTRIBUT_REF"); //$NON-NLS-1$
				break;
			case CompletionProposal.FIELD_IMPORT :
				buffer.append("FIELD_IMPORT"); //$NON-NLS-1$
				break;
			case CompletionProposal.METHOD_IMPORT :
				buffer.append("METHOD_IMPORT"); //$NON-NLS-1$
				break;
			case CompletionProposal.TYPE_IMPORT :
				buffer.append("TYPE_IMPORT"); //$NON-NLS-1$
				break;
			case CompletionProposal.CONSTRUCTOR_INVOCATION :
				buffer.append("CONSTRUCTOR_INVOCATION"); //$NON-NLS-1$
				break;
			case CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION :
				buffer.append("ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION"); //$NON-NLS-1$
				break;
			default :
				buffer.append("PROPOSAL"); //$NON-NLS-1$
				break;

		}

		buffer.append("{\n");//$NON-NLS-1$
		printDebugTab(tab, buffer);
		buffer.append("\tCompletion[").append(proposal.getCompletion() == null ? "null".toCharArray() : proposal.getCompletion()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		printDebugTab(tab, buffer);
		buffer.append("\tDeclarationSignature[").append(proposal.getDeclarationSignature() == null ? "null".toCharArray() : proposal.getDeclarationSignature()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		printDebugTab(tab, buffer);
		buffer.append("\tDeclarationKey[").append(proposal.getDeclarationKey() == null ? "null".toCharArray() : proposal.getDeclarationKey()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		printDebugTab(tab, buffer);
		buffer.append("\tSignature[").append(proposal.getSignature() == null ? "null".toCharArray() : proposal.getSignature()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		printDebugTab(tab, buffer);
		buffer.append("\tKey[").append(proposal.getKey() == null ? "null".toCharArray() : proposal.getKey()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		printDebugTab(tab, buffer);
		buffer.append("\tName[").append(proposal.getName() == null ? "null".toCharArray() : proposal.getName()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$

		printDebugTab(tab, buffer);
		buffer.append("\tFlags[");//$NON-NLS-1$
		int flags = proposal.getFlags();
		buffer.append(Flags.toString(flags));
		if((flags & Flags.AccInterface) != 0) buffer.append("interface ");//$NON-NLS-1$
		if((flags & Flags.AccEnum) != 0) buffer.append("enum ");//$NON-NLS-1$
		buffer.append("]\n"); //$NON-NLS-1$

		CompletionProposal[] proposals = proposal.getRequiredProposals();
		if(proposals != null) {
			printDebugTab(tab, buffer);
			buffer.append("\tRequiredProposals[");//$NON-NLS-1$
			for (int i = 0; i < proposals.length; i++) {
				buffer.append("\n"); //$NON-NLS-1$
				printDebug(proposals[i], tab + 2, buffer);
			}
			printDebugTab(tab, buffer);
			buffer.append("\n\t]\n"); //$NON-NLS-1$
		}

		printDebugTab(tab, buffer);
		buffer.append("\tCompletionLocation[").append(proposal.getCompletionLocation()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$
		int start = proposal.getReplaceStart();
		int end = proposal.getReplaceEnd();
		printDebugTab(tab, buffer);
		buffer.append("\tReplaceStart[").append(start).append("]"); //$NON-NLS-1$ //$NON-NLS-2$
		buffer.append("-ReplaceEnd[").append(end).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$
		start = proposal.getTokenStart();
		end = proposal.getTokenEnd();
		printDebugTab(tab, buffer);
		buffer.append("\tTokenStart[").append(start).append("]"); //$NON-NLS-1$ //$NON-NLS-2$
		buffer.append("-TokenEnd[").append(end).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$
		if (this.source != null) {
			printDebugTab(tab, buffer);
			buffer.append("\tReplacedText[").append(this.source, start, end-start).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$
		}
		printDebugTab(tab, buffer);
		buffer.append("\tTokenStart[").append(proposal.getTokenStart()).append("]"); //$NON-NLS-1$ //$NON-NLS-2$
		buffer.append("-TokenEnd[").append(proposal.getTokenEnd()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$
		printDebugTab(tab, buffer);
		buffer.append("\tRelevance[").append(proposal.getRelevance()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$

		printDebugTab(tab, buffer);
		buffer.append("}\n");//$NON-NLS-1$
	}

	private void printDebugTab(int tab, StringBuffer buffer) {
		for (int i = 0; i < tab; i++) {
			buffer.append('\t');
		}
	}
	
	private void proposeConstructor(AcceptedConstructor deferredProposal, Scope scope) {
		if (deferredProposal.proposeConstructor) {
			proposeConstructor(
					deferredProposal.simpleTypeName,
					deferredProposal.parameterCount,
					deferredProposal.signature,
					deferredProposal.parameterTypes,
					deferredProposal.parameterNames,
					deferredProposal.modifiers,
					deferredProposal.packageName,
					deferredProposal.typeModifiers,
					deferredProposal.accessibility,
					deferredProposal.simpleTypeName,
					deferredProposal.fullyQualifiedName,
					deferredProposal.mustBeQualified,
					scope,
					deferredProposal.extraFlags);
		}
	}
	
	private void proposeConstructor(
			char[] simpleTypeName,
			int parameterCount,
			char[] signature,
			char[][] parameterTypes,
			char[][] parameterNames,
			int modifiers,
			char[] packageName,
			int typeModifiers,
			int accessibility,
			char[] typeName,
			char[] fullyQualifiedName,
			boolean isQualified,
			Scope scope,
			int extraFlags) {
		char[] typeCompletion = fullyQualifiedName;
		if(isQualified) {
			if (packageName == null || packageName.length == 0)
				if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
					return; // ignore types from the default package from outside it
		} else {
			typeCompletion = simpleTypeName;
		}

		int relevance = computeBaseRelevance();
		relevance += computeRelevanceForResolution();
		relevance += computeRelevanceForInterestingProposal();
		relevance += computeRelevanceForRestrictions(accessibility);
		relevance += computeRelevanceForCaseMatching(this.completionToken, simpleTypeName);
		relevance += computeRelevanceForExpectingType(packageName, simpleTypeName);
		relevance += computeRelevanceForQualification(isQualified);

		boolean isInterface = false;
		int kind = typeModifiers & (ClassFileConstants.AccInterface | ClassFileConstants.AccEnum | ClassFileConstants.AccAnnotation);
		switch (kind) {
			case ClassFileConstants.AccAnnotation:
			case ClassFileConstants.AccAnnotation | ClassFileConstants.AccInterface:
				relevance += computeRelevanceForAnnotation();
				relevance += computeRelevanceForInterface();
				isInterface = true;
				break;
			case ClassFileConstants.AccEnum:
				relevance += computeRelevanceForEnum();
				break;
			case ClassFileConstants.AccInterface:
				relevance += computeRelevanceForInterface();
				isInterface = true;
				break;
			default:
				relevance += computeRelevanceForClass();
				relevance += computeRelevanceForException(simpleTypeName);
				break;
		}
		
		char[] completion;
		if (this.source != null
					&& this.source.length > this.endPosition
					&& this.source[this.endPosition] == '(') {
			completion = CharOperation.NO_CHAR;
		} else {
			completion = new char[] { '(', ')' };
		}
		
		InternalCompletionProposal typeProposal = createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
		typeProposal.nameLookup = this.nameEnvironment.nameLookup;
		typeProposal.completionEngine = this;
		typeProposal.setDeclarationSignature(packageName);
		typeProposal.setSignature(createNonGenericTypeSignature(packageName, typeName));
		typeProposal.setPackageName(packageName);
		typeProposal.setTypeName(typeName);
		typeProposal.setCompletion(typeCompletion);
		typeProposal.setFlags(typeModifiers);
		typeProposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
		typeProposal.setTokenRange(this.startPosition - this.offset, this.endPosition - this.offset);
		typeProposal.setRelevance(relevance);
		
		switch (parameterCount) {
			case -1: // default constructor
				int flags = Flags.AccPublic;
				if (Flags.isDeprecated(typeModifiers)) {
					flags |= Flags.AccDeprecated;
				}
				
				if (isInterface || (typeModifiers & ClassFileConstants.AccAbstract) != 0) {
					this.noProposal = false;
					if(!isIgnored(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)) {
						InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, this.actualCompletionPosition);
						proposal.setDeclarationSignature(createNonGenericTypeSignature(packageName, typeName));
						proposal.setDeclarationKey(createBindingKey(packageName, typeName));
						proposal.setSignature(DEFAULT_CONSTRUCTOR_SIGNATURE);
						proposal.setDeclarationPackageName(packageName);
						proposal.setDeclarationTypeName(typeName);
						proposal.setParameterPackageNames(CharOperation.NO_CHAR_CHAR);
						proposal.setParameterTypeNames(CharOperation.NO_CHAR_CHAR);
						proposal.setParameterNames(CharOperation.NO_CHAR_CHAR);
						proposal.setName(simpleTypeName);
						proposal.setRequiredProposals(new CompletionProposal[]{typeProposal});
						proposal.setIsContructor(true);
						proposal.setCompletion(completion);
						proposal.setFlags(flags);
						proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
						proposal.setRelevance(relevance);
						this.requestor.accept(proposal);
						if(DEBUG) {
							this.printDebug(proposal);
						}
					}
				} else {
					this.noProposal = false;
					if(!isIgnored(CompletionProposal.CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)) {
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.CONSTRUCTOR_INVOCATION, this.actualCompletionPosition);
						proposal.setDeclarationSignature(createNonGenericTypeSignature(packageName, typeName));
						proposal.setSignature(DEFAULT_CONSTRUCTOR_SIGNATURE);
						proposal.setDeclarationPackageName(packageName);
						proposal.setDeclarationTypeName(typeName);
						proposal.setParameterPackageNames(CharOperation.NO_CHAR_CHAR);
						proposal.setParameterTypeNames(CharOperation.NO_CHAR_CHAR);
						proposal.setParameterNames(CharOperation.NO_CHAR_CHAR);
						proposal.setName(simpleTypeName);
						proposal.setRequiredProposals(new CompletionProposal[]{typeProposal});
						proposal.setIsContructor(true);
						proposal.setCompletion(completion);
						proposal.setFlags(flags);
						proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
						proposal.setRelevance(relevance);
						this.requestor.accept(proposal);
						if(DEBUG) {
							this.printDebug(proposal);
						}
					}
				}
				break;
			case 0: // constructor with no parameter
				
				if ((typeModifiers & ClassFileConstants.AccAbstract) != 0) {
					this.noProposal = false;
					if(!isIgnored(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)) {
						InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, this.actualCompletionPosition);
						proposal.setDeclarationSignature(createNonGenericTypeSignature(packageName, typeName));
						proposal.setDeclarationKey(createBindingKey(packageName, typeName));
						proposal.setSignature(DEFAULT_CONSTRUCTOR_SIGNATURE);
						proposal.setDeclarationPackageName(packageName);
						proposal.setDeclarationTypeName(typeName);
						proposal.setParameterPackageNames(CharOperation.NO_CHAR_CHAR);
						proposal.setParameterTypeNames(CharOperation.NO_CHAR_CHAR);
						proposal.setParameterNames(CharOperation.NO_CHAR_CHAR);
						proposal.setName(simpleTypeName);
						proposal.setRequiredProposals(new CompletionProposal[]{typeProposal});
						proposal.setIsContructor(true);
						proposal.setCompletion(completion);
						proposal.setFlags(modifiers);
						proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
						proposal.setRelevance(relevance);
						this.requestor.accept(proposal);
						if(DEBUG) {
							this.printDebug(proposal);
						}
					}
				} else {
					this.noProposal = false;
					if(!isIgnored(CompletionProposal.CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)) {
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.CONSTRUCTOR_INVOCATION, this.actualCompletionPosition);
						proposal.setDeclarationSignature(createNonGenericTypeSignature(packageName, typeName));
						proposal.setSignature(DEFAULT_CONSTRUCTOR_SIGNATURE);
						proposal.setDeclarationPackageName(packageName);
						proposal.setDeclarationTypeName(typeName);
						proposal.setParameterPackageNames(CharOperation.NO_CHAR_CHAR);
						proposal.setParameterTypeNames(CharOperation.NO_CHAR_CHAR);
						proposal.setParameterNames(CharOperation.NO_CHAR_CHAR);
						proposal.setName(simpleTypeName);
						proposal.setRequiredProposals(new CompletionProposal[]{typeProposal});
						proposal.setIsContructor(true);
						proposal.setCompletion(completion);
						proposal.setFlags(modifiers);
						proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
						proposal.setRelevance(relevance);
						this.requestor.accept(proposal);
						if(DEBUG) {
							this.printDebug(proposal);
						}
					}
				}
				break;
			default: // constructor with parameter
				if (signature == null) {
					// resolve type to found parameter types
					signature = getResolvedSignature(parameterTypes, fullyQualifiedName, parameterCount, scope);
					if (signature == null) return;
				} else {
					signature = CharOperation.replaceOnCopy(signature, '/', '.');
				}
				
				int parameterNamesLength = parameterNames == null ? 0 : parameterNames.length;
				if (parameterCount != parameterNamesLength) {
					parameterNames = null;
				}
				
				if ((typeModifiers & ClassFileConstants.AccAbstract) != 0) {
					this.noProposal = false;
					if(!isIgnored(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)) {
						InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, this.actualCompletionPosition);
						proposal.setDeclarationSignature(createNonGenericTypeSignature(packageName, typeName));
						proposal.setDeclarationKey(createBindingKey(packageName, typeName));
						proposal.setSignature(signature);
						proposal.setDeclarationPackageName(packageName);
						proposal.setDeclarationTypeName(typeName);
						proposal.setParameterPackageNames(CharOperation.NO_CHAR_CHAR);
						proposal.setParameterTypeNames(CharOperation.NO_CHAR_CHAR);
						if (parameterNames != null) {
							proposal.setParameterNames(parameterNames);
						} else {
							proposal.setHasNoParameterNamesFromIndex(true);
						}
						proposal.setName(simpleTypeName);
						proposal.setRequiredProposals(new CompletionProposal[]{typeProposal});
						proposal.setIsContructor(true);
						proposal.setCompletion(completion);
						proposal.setFlags(modifiers);
						proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
						proposal.setRelevance(relevance);
						this.requestor.accept(proposal);
						if(DEBUG) {
							this.printDebug(proposal);
						}
					}
				} else {
					this.noProposal = false;
					if(!isIgnored(CompletionProposal.CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)) {
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.CONSTRUCTOR_INVOCATION, this.actualCompletionPosition);
						proposal.setDeclarationSignature(createNonGenericTypeSignature(packageName, typeName));
						proposal.setSignature(signature);
						proposal.setDeclarationPackageName(packageName);
						proposal.setDeclarationTypeName(typeName);
						proposal.setParameterPackageNames(CharOperation.NO_CHAR_CHAR);
						proposal.setParameterTypeNames(CharOperation.NO_CHAR_CHAR);
						if (parameterNames != null) {
							proposal.setParameterNames(parameterNames);
						} else {
							proposal.setHasNoParameterNamesFromIndex(true);
						}
						proposal.setName(simpleTypeName);
						proposal.setRequiredProposals(new CompletionProposal[]{typeProposal});
						proposal.setIsContructor(true);
						proposal.setCompletion(completion);
						proposal.setFlags(modifiers);
						proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
						proposal.setRelevance(relevance);
						
						this.requestor.accept(proposal);
						if(DEBUG) {
							this.printDebug(proposal);
						}
					}
				}
				break;
		}
	}

	private void proposeNewMethod(char[] token, ReferenceBinding reference) {
		if(!this.requestor.isIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION)) {
			int relevance = computeBaseRelevance();
			relevance += computeRelevanceForResolution();
			relevance += computeRelevanceForInterestingProposal();
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for new method

			InternalCompletionProposal proposal =  createProposal(CompletionProposal.POTENTIAL_METHOD_DECLARATION, this.actualCompletionPosition);
			proposal.setDeclarationSignature(getSignature(reference));
			proposal.setSignature(
					createMethodSignature(
							CharOperation.NO_CHAR_CHAR,
							CharOperation.NO_CHAR_CHAR,
							CharOperation.NO_CHAR,
							VOID));
			proposal.setDeclarationPackageName(reference.qualifiedPackageName());
			proposal.setDeclarationTypeName(reference.qualifiedSourceName());

			//proposal.setPackageName(null);
			proposal.setTypeName(VOID);
			proposal.setName(token);
			//proposal.setParameterPackageNames(null);
			//proposal.setParameterTypeNames(null);
			//proposal.setPackageName(null);
			proposal.setCompletion(token);
			proposal.setFlags(Flags.AccPublic);
			proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
			proposal.setRelevance(relevance);
			this.requestor.accept(proposal);
			if(DEBUG) {
				this.printDebug(proposal);
			}
		}
	}

	private void proposeType(
			char[] packageName,
			char[] simpleTypeName,
			int modifiers,
			int accessibility,
			char[] typeName,
			char[] fullyQualifiedName,
			boolean isQualified,
			Scope scope) {
		char[] completionName = fullyQualifiedName;
		if(isQualified) {
			if (packageName == null || packageName.length == 0)
				if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
					return; // ignore types from the default package from outside it
		} else {
			completionName = simpleTypeName;
		}

		TypeBinding guessedType = null;
		if ((modifiers & ClassFileConstants.AccAnnotation) != 0 &&
				this.assistNodeIsAnnotation &&
				(this.targetedElement & TagBits.AnnotationTargetMASK) != 0) {
			char[][] cn = CharOperation.splitOn('.', fullyQualifiedName);

			TypeReference ref;
			if (cn.length == 1) {
				ref = new SingleTypeReference(simpleTypeName, 0);
			} else {
				ref = new QualifiedTypeReference(cn,new long[cn.length]);
			}

			switch (scope.kind) {
				case Scope.METHOD_SCOPE :
				case Scope.BLOCK_SCOPE :
					guessedType = ref.resolveType((BlockScope)scope);
					break;
				case Scope.CLASS_SCOPE :
					guessedType = ref.resolveType((ClassScope)scope);
					break;
			}

			if (guessedType == null || !guessedType.isValidBinding()) return;

			if (!hasPossibleAnnotationTarget(guessedType, scope)) return;
		}

		int relevance = computeBaseRelevance();
		relevance += computeRelevanceForResolution();
		relevance += computeRelevanceForInterestingProposal();
		relevance += computeRelevanceForRestrictions(accessibility);
		relevance += computeRelevanceForCaseMatching(this.completionToken, simpleTypeName);
		relevance += computeRelevanceForExpectingType(packageName, simpleTypeName);
		relevance += computeRelevanceForQualification(isQualified);

		int kind = modifiers & (ClassFileConstants.AccInterface | ClassFileConstants.AccEnum | ClassFileConstants.AccAnnotation);
		switch (kind) {
			case ClassFileConstants.AccAnnotation:
			case ClassFileConstants.AccAnnotation | ClassFileConstants.AccInterface:
				relevance += computeRelevanceForAnnotation();
				if (guessedType != null) relevance += computeRelevanceForAnnotationTarget(guessedType);
				relevance += computeRelevanceForInterface();
				break;
			case ClassFileConstants.AccEnum:
				relevance += computeRelevanceForEnum();
				break;
			case ClassFileConstants.AccInterface:
				relevance += computeRelevanceForInterface();
				break;
			default:
				relevance += computeRelevanceForClass();
				relevance += computeRelevanceForException(simpleTypeName);
				break;
		}

		this.noProposal = false;
		if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
			createTypeProposal(packageName, typeName, modifiers, accessibility, completionName, relevance);
		}
	}

	protected void reset() {

		super.reset(false);
		this.knownPkgs = new HashtableOfObject(10);
		this.knownTypes = new HashtableOfObject(10);
		if (this.noCacheNameEnvironment != null) {
			this.noCacheNameEnvironment.cleanup();
			this.noCacheNameEnvironment = null;
			JavaModelManager.getJavaModelManager().flushZipFiles(this);
		}
	}

	private void setSourceAndTokenRange(int start, int end) {
		this.setSourceAndTokenRange(start, end, true);
	}

	private void setSourceAndTokenRange(int start, int end, boolean emptyTokenAdjstment) {
		this.setSourceRange(start, end, emptyTokenAdjstment);
		this.setTokenRange(start, end, emptyTokenAdjstment);
	}

	private void setSourceRange(int start, int end) {
		this.setSourceRange(start, end, true);
	}

	private void setSourceRange(int start, int end, boolean emptyTokenAdjstment) {
		this.startPosition = start;
		if(emptyTokenAdjstment) {
			int endOfEmptyToken = ((CompletionScanner)this.parser.scanner).endOfEmptyToken;
			this.endPosition = endOfEmptyToken > end ? endOfEmptyToken + 1 : end + 1;
		} else {
			this.endPosition = end + 1;
		}
	}

	private void setTokenRange(int start, int end) {
		this.setTokenRange(start, end, true);
	}
	private void setTokenRange(int start, int end, boolean emptyTokenAdjstment) {
		this.tokenStart = start;
		if(emptyTokenAdjstment) {
			int endOfEmptyToken = ((CompletionScanner)this.parser.scanner).endOfEmptyToken;
			this.tokenEnd = endOfEmptyToken > end ? endOfEmptyToken + 1 : end + 1;
		} else {
			this.tokenEnd = end + 1;
		}
	}

	private char[] substituteMethodTypeParameterName(char firstName, char startChar, char endChar, char[][] excludedNames, char[][] otherParameterNames) {
		char name = firstName;
		next : while (true) {
			for (int i = 0 ; i < excludedNames.length ; i++){
				if(excludedNames[i].length == 1 && ScannerHelper.toLowerCase(excludedNames[i][0]) == ScannerHelper.toLowerCase(name)) {
					name++;
					if(name > endChar)
						name = startChar;
					if(name == firstName)
						return substituteMethodTypeParameterName(new char[]{firstName}, excludedNames, otherParameterNames);
					continue next;
				}
			}

			for (int i = 0; i < otherParameterNames.length; i++) {
				if(otherParameterNames[i].length == 1 && ScannerHelper.toLowerCase(otherParameterNames[i][0]) == ScannerHelper.toLowerCase(name)) {
					name++;
					if(name > endChar)
						name = startChar;
					if(name == firstName)
						return substituteMethodTypeParameterName(new char[]{firstName}, excludedNames, otherParameterNames);
					continue next;
				}
			}
			break next;
		}
		return new char[]{name};
	}

	private char[] substituteMethodTypeParameterName(char[] firstName, char[][] excludedNames, char[][] otherParameterNames) {
		char[] name = firstName;
		int count = 2;
		next : while(true) {
			for(int k = 0 ; k < excludedNames.length ; k++){
				if(CharOperation.equals(name, excludedNames[k], false)) {
					name = CharOperation.concat(firstName, String.valueOf(count++).toCharArray());
					continue next;
				}
			}
			for (int i = 0; i < otherParameterNames.length; i++) {
				if(CharOperation.equals(name, otherParameterNames[i], false)) {
					name = CharOperation.concat(firstName, String.valueOf(count++).toCharArray());
					continue next;
				}
			}
			break next;
		}
		return name;
	}

	private char[][] substituteMethodTypeParameterNames(TypeVariableBinding[] typeVariables, char[][] excludedNames) {
		char[][] substituedParameterNames = new char[typeVariables.length][];

		for (int i = 0; i < substituedParameterNames.length; i++) {
			substituedParameterNames[i] = typeVariables[i].sourceName;
		}

		boolean foundConflicts = false;

		nextTypeParameter : for (int i = 0; i < typeVariables.length; i++) {
			TypeVariableBinding typeVariableBinding = typeVariables[i];
			char[] methodParameterName = typeVariableBinding.sourceName;

			for (int j = 0; j < excludedNames.length; j++) {
				char[] typeParameterName = excludedNames[j];
				if(CharOperation.equals(typeParameterName, methodParameterName, false)) {
					char[] substitution;
					if(methodParameterName.length == 1) {
						if(ScannerHelper.isUpperCase(methodParameterName[0])) {
							substitution = substituteMethodTypeParameterName(methodParameterName[0], 'A', 'Z', excludedNames, substituedParameterNames);
						} else {
							substitution = substituteMethodTypeParameterName(methodParameterName[0], 'a', 'z', excludedNames, substituedParameterNames);
						}
					} else {
						substitution = substituteMethodTypeParameterName(methodParameterName, excludedNames, substituedParameterNames);
					}
					substituedParameterNames[i] = substitution;

					foundConflicts = true;
					continue nextTypeParameter;
				}
			}
		}

		if(foundConflicts) return substituedParameterNames;
		return null;
	}
}