/*******************************************************************************
 * Copyright (c) 2000, 2011 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.Iterator;
import java.util.Locale;
import java.util.Map;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.jdt.core.IBuffer;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IOpenable;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.WorkingCopyOwner;
import org.eclipse.jdt.core.compiler.*;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.jdt.core.search.IJavaSearchScope;
import org.eclipse.jdt.core.search.SearchPattern;
import org.eclipse.jdt.core.search.TypeNameMatch;
import org.eclipse.jdt.core.search.TypeNameMatchRequestor;
import org.eclipse.jdt.internal.codeassist.impl.*;
import org.eclipse.jdt.internal.codeassist.select.*;
import org.eclipse.jdt.internal.compiler.*;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
import org.eclipse.jdt.internal.compiler.env.*;
import org.eclipse.jdt.internal.compiler.ast.*;
import org.eclipse.jdt.internal.compiler.lookup.*;
import org.eclipse.jdt.internal.compiler.parser.*;
import org.eclipse.jdt.internal.compiler.problem.*;
import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
import org.eclipse.jdt.internal.compiler.util.ObjectVector;
import org.eclipse.jdt.internal.core.BinaryTypeConverter;
import org.eclipse.jdt.internal.core.ClassFile;
import org.eclipse.jdt.internal.core.JavaModelManager;
import org.eclipse.jdt.internal.core.SearchableEnvironment;
import org.eclipse.jdt.internal.core.SelectionRequestor;
import org.eclipse.jdt.internal.core.SourceType;
import org.eclipse.jdt.internal.core.SourceTypeElementInfo;
import org.eclipse.jdt.internal.core.search.BasicSearchEngine;
import org.eclipse.jdt.internal.core.search.TypeNameMatchRequestorWrapper;
import org.eclipse.jdt.internal.core.util.ASTNodeFinder;
import org.eclipse.jdt.internal.core.util.HashSetOfCharArrayArray;

/**
 * The selection engine is intended to infer the nature of a selected name in some
 * source code. This name can be qualified.
 *
 * Selection is resolving context using a name environment (no need to search), assuming
 * the source where selection occurred is correct and will not perform any completion
 * attempt. If this was the desired behavior, a call to the CompletionEngine should be
 * performed instead.
 */
public final class SelectionEngine extends Engine implements ISearchRequestor {
	
	private static class SelectionTypeNameMatchRequestorWrapper extends TypeNameMatchRequestorWrapper {
		
		class AcceptedType {
			public int modifiers;
			public char[] packageName;
			public char[] simpleTypeName;
			public String path;
			public AccessRestriction access;
			
			public AcceptedType(int modifiers, char[] packageName, char[] simpleTypeName, String path, AccessRestriction access) {
				this.modifiers = modifiers;
				this.packageName = packageName;
				this.simpleTypeName = simpleTypeName;
				this.path = path;
				this.access = access;
			}
		}
		
		private ImportReference[] importReferences;
		
		private boolean importCachesNodeInitialized = false;
		private ImportReference[] onDemandImportsNodeCache;
		private int onDemandImportsNodeCacheCount;
		private char[][][] importsNodeCache;
		private int importsNodeCacheCount;
		
		private HashtableOfObject onDemandFound = new HashtableOfObject();
		private ObjectVector notImportedFound = new ObjectVector();
		
		public SelectionTypeNameMatchRequestorWrapper(TypeNameMatchRequestor requestor, IJavaSearchScope scope, ImportReference[] importReferences) {
			super(requestor, scope);
			this.importReferences = importReferences;
		}
		
		public void acceptType(int modifiers, char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path, AccessRestriction access) {
			if (enclosingTypeNames != null && enclosingTypeNames.length > 0) return;
			
			if (!this.importCachesNodeInitialized) initializeImportNodeCaches();
			
			char[] fullyQualifiedTypeName = CharOperation.concat(packageName, simpleTypeName, '.');
			
			for (int i = 0; i < this.importsNodeCacheCount; i++) {
				char[][] importName = this.importsNodeCache[i];
				if (CharOperation.equals(importName[0], simpleTypeName)) {
					
					if(CharOperation.equals(importName[1], fullyQualifiedTypeName)) {
						super.acceptType(modifiers, packageName, simpleTypeName, enclosingTypeNames, path, access);
					}
					return;
				}
			}
			
			for (int i = 0; i < this.onDemandImportsNodeCacheCount; i++) {
				char[][] importName = this.onDemandImportsNodeCache[i].tokens;
				char[] importFlatName = CharOperation.concatWith(importName, '.');
				
				if (CharOperation.equals(importFlatName, packageName)) {
					
					this.onDemandFound.put(simpleTypeName, simpleTypeName);
					super.acceptType(modifiers, packageName, simpleTypeName, enclosingTypeNames, path, access);
					return;
				}
			}
			
			
			this.notImportedFound.add(new AcceptedType(modifiers, packageName, simpleTypeName, path, access));
		}
		
		public void acceptNotImported() {
			int size = this.notImportedFound.size();
			for (int i = 0; i < size; i++) {
				AcceptedType acceptedType = (AcceptedType)this.notImportedFound.elementAt(i);
				
				if (this.onDemandFound.get(acceptedType.simpleTypeName) == null) {
					super.acceptType(
							acceptedType.modifiers,
							acceptedType.packageName,
							acceptedType.simpleTypeName,
							null,
							acceptedType.path,
							acceptedType.access);
				}
			}
		}
		
		public void initializeImportNodeCaches() {
			int length = this.importReferences == null ? 0 : this.importReferences.length;
			
			for (int i = 0; i < length; i++) {
				ImportReference importReference = this.importReferences[i];
				if((importReference.bits & ASTNode.OnDemand) != 0) {
					if(this.onDemandImportsNodeCache == null) {
						this.onDemandImportsNodeCache = new ImportReference[length - i];
					}
					this.onDemandImportsNodeCache[this.onDemandImportsNodeCacheCount++] =
						importReference;
				} else {
					if(this.importsNodeCache == null) {
						this.importsNodeCache = new char[length - i][][];
					}
					
					
					this.importsNodeCache[this.importsNodeCacheCount++] = new char[][]{
							importReference.tokens[importReference.tokens.length - 1],
							CharOperation.concatWith(importReference.tokens, '.')
						};
				}
			}
			
			this.importCachesNodeInitialized = true;
		}
	}

	public static boolean DEBUG = false;
	public static boolean PERF = false;

	SelectionParser parser;
	ISelectionRequestor requestor;
	WorkingCopyOwner owner;

	boolean acceptedAnswer;

	private int actualSelectionStart;
	private int actualSelectionEnd;
	private char[] selectedIdentifier;

	private char[][][] acceptedClasses;
	private int[] acceptedClassesModifiers;
	private char[][][] acceptedInterfaces;
	private int[] acceptedInterfacesModifiers;
	private char[][][] acceptedEnums;
	private int[] acceptedEnumsModifiers;
	private char[][][] acceptedAnnotations;
	private int[] acceptedAnnotationsModifiers;
	int acceptedClassesCount;
	int acceptedInterfacesCount;
	int acceptedEnumsCount;
	int acceptedAnnotationsCount;

	boolean noProposal = true;
	CategorizedProblem problem = null;

	/**
	 * The SelectionEngine is responsible for computing the selected object.
	 *
	 * 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.core.SearchableEnvironment
	 *      used to resolve type/package references and search for types/packages
	 *      based on partial names.
	 *
	 *  @param requestor org.eclipse.jdt.internal.codeassist.ISelectionRequestor
	 *      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 SelectionEngine(
		SearchableEnvironment nameEnvironment,
		ISelectionRequestor requestor,
		Map settings,
		WorkingCopyOwner owner) {

		super(settings);

		this.requestor = requestor;
		this.nameEnvironment = nameEnvironment;

		ProblemReporter problemReporter =
			new ProblemReporter(
				DefaultErrorHandlingPolicies.proceedWithAllProblems(),
				this.compilerOptions,
				new DefaultProblemFactory(Locale.getDefault())) {

			public CategorizedProblem createProblem(
				char[] fileName,
				int problemId,
				String[] problemArguments,
				String[] messageArguments,
				int severity,
				int problemStartPosition,
				int problemEndPosition,
				int lineNumber,
				int columnNumber) {
				CategorizedProblem pb =  super.createProblem(
					fileName,
					problemId,
					problemArguments,
					messageArguments,
					severity,
					problemStartPosition,
					problemEndPosition,
					lineNumber,
					columnNumber);
					if(SelectionEngine.this.problem == null && pb.isError() && (pb.getID() & IProblem.Syntax) == 0) {
						SelectionEngine.this.problem = pb;
					}

					return pb;
			}
		};
		this.lookupEnvironment =
			new LookupEnvironment(this, this.compilerOptions, problemReporter, nameEnvironment);
		this.parser = new SelectionParser(problemReporter);
		this.owner = owner;
	}
	
	public void acceptConstructor(
			int modifiers,
			char[] simpleTypeName,
			int parameterCount,
			char[] signature,
			char[][] parameterTypes,
			char[][] parameterNames,
			int typeModifiers,
			char[] packageName,
			int extraFlags,
			String path,
			AccessRestriction access) {
		// constructors aren't searched
	}

	public void acceptType(char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, int modifiers, AccessRestriction accessRestriction) {
		char[] typeName = enclosingTypeNames == null ?
				simpleTypeName :
					CharOperation.concat(
						CharOperation.concatWith(enclosingTypeNames, '.'),
						simpleTypeName,
						'.');

		if (CharOperation.equals(simpleTypeName, this.selectedIdentifier)) {
			char[] flatEnclosingTypeNames =
				enclosingTypeNames == null || enclosingTypeNames.length == 0 ?
						null :
							CharOperation.concatWith(enclosingTypeNames, '.');
			if(mustQualifyType(packageName, simpleTypeName, flatEnclosingTypeNames, modifiers)) {
				int length = 0;
				int kind = modifiers & (ClassFileConstants.AccInterface | ClassFileConstants.AccEnum | ClassFileConstants.AccAnnotation);
				switch (kind) {
					case ClassFileConstants.AccAnnotation:
					case ClassFileConstants.AccAnnotation | ClassFileConstants.AccInterface:
						char[][] acceptedAnnotation = new char[2][];
						acceptedAnnotation[0] = packageName;
						acceptedAnnotation[1] = typeName;

						if(this.acceptedAnnotations == null) {
							this.acceptedAnnotations = new char[10][][];
							this.acceptedAnnotationsModifiers = new int[10];
							this.acceptedAnnotationsCount = 0;
						}
						length = this.acceptedAnnotations.length;
						if(length == this.acceptedAnnotationsCount) {
							int newLength = (length + 1)* 2;
							System.arraycopy(this.acceptedAnnotations, 0, this.acceptedAnnotations = new char[newLength][][], 0, length);
							System.arraycopy(this.acceptedAnnotationsModifiers, 0, this.acceptedAnnotationsModifiers = new int[newLength], 0, length);
						}
						this.acceptedAnnotationsModifiers[this.acceptedAnnotationsCount] = modifiers;
						this.acceptedAnnotations[this.acceptedAnnotationsCount++] = acceptedAnnotation;
						break;
					case ClassFileConstants.AccEnum:
						char[][] acceptedEnum = new char[2][];
						acceptedEnum[0] = packageName;
						acceptedEnum[1] = typeName;

						if(this.acceptedEnums == null) {
							this.acceptedEnums = new char[10][][];
							this.acceptedEnumsModifiers = new int[10];
							this.acceptedEnumsCount = 0;
						}
						length = this.acceptedEnums.length;
						if(length == this.acceptedEnumsCount) {
							int newLength = (length + 1)* 2;
							System.arraycopy(this.acceptedEnums, 0, this.acceptedEnums = new char[newLength][][], 0, length);
							System.arraycopy(this.acceptedEnumsModifiers, 0, this.acceptedEnumsModifiers = new int[newLength], 0, length);
						}
						this.acceptedEnumsModifiers[this.acceptedEnumsCount] = modifiers;
						this.acceptedEnums[this.acceptedEnumsCount++] = acceptedEnum;
						break;
					case ClassFileConstants.AccInterface:
						char[][] acceptedInterface= new char[2][];
						acceptedInterface[0] = packageName;
						acceptedInterface[1] = typeName;

						if(this.acceptedInterfaces == null) {
							this.acceptedInterfaces = new char[10][][];
							this.acceptedInterfacesModifiers = new int[10];
							this.acceptedInterfacesCount = 0;
						}
						length = this.acceptedInterfaces.length;
						if(length == this.acceptedInterfacesCount) {
							int newLength = (length + 1)* 2;
							System.arraycopy(this.acceptedInterfaces, 0, this.acceptedInterfaces = new char[newLength][][], 0, length);
							System.arraycopy(this.acceptedInterfacesModifiers, 0, this.acceptedInterfacesModifiers = new int[newLength], 0, length);
						}
						this.acceptedInterfacesModifiers[this.acceptedInterfacesCount] = modifiers;
						this.acceptedInterfaces[this.acceptedInterfacesCount++] = acceptedInterface;
						break;
					default:
						char[][] acceptedClass = new char[2][];
						acceptedClass[0] = packageName;
						acceptedClass[1] = typeName;

						if(this.acceptedClasses == null) {
							this.acceptedClasses = new char[10][][];
							this.acceptedClassesModifiers = new int[10];
							this.acceptedClassesCount = 0;
						}
						length = this.acceptedClasses.length;
						if(length == this.acceptedClassesCount) {
							int newLength = (length + 1)* 2;
							System.arraycopy(this.acceptedClasses, 0, this.acceptedClasses = new char[newLength][][], 0, length);
							System.arraycopy(this.acceptedClassesModifiers, 0, this.acceptedClassesModifiers = new int[newLength], 0, length);
						}
						this.acceptedClassesModifiers[this.acceptedClassesCount] = modifiers;
						this.acceptedClasses[this.acceptedClassesCount++] = acceptedClass;
						break;
				}
			} else {
				this.noProposal = false;
				this.requestor.acceptType(
					packageName,
					typeName,
					modifiers,
					false,
					null,
					this.actualSelectionStart,
					this.actualSelectionEnd);
				this.acceptedAnswer = true;
			}
		}
	}

	/**
	 * One result of the search consists of a new package.
	 * @param packageName char[]
	 *
	 * 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) {
		// implementation of interface method
	}

	private void acceptQualifiedTypes() {
		if(this.acceptedClasses != null){
			this.acceptedAnswer = true;
			for (int i = 0; i < this.acceptedClassesCount; i++) {
				this.noProposal = false;
				this.requestor.acceptType(
					this.acceptedClasses[i][0],
					this.acceptedClasses[i][1],
					this.acceptedClassesModifiers[i],
					false,
					null,
					this.actualSelectionStart,
					this.actualSelectionEnd);
			}
			this.acceptedClasses = null;
			this.acceptedClassesModifiers = null;
			this.acceptedClassesCount = 0;
		}
		if(this.acceptedInterfaces != null){
			this.acceptedAnswer = true;
			for (int i = 0; i < this.acceptedInterfacesCount; i++) {
				this.noProposal = false;
				this.requestor.acceptType(
					this.acceptedInterfaces[i][0],
					this.acceptedInterfaces[i][1],
					this.acceptedInterfacesModifiers[i],
					false,
					null,
					this.actualSelectionStart,
					this.actualSelectionEnd);
			}
			this.acceptedInterfaces = null;
			this.acceptedInterfacesModifiers = null;
			this.acceptedInterfacesCount = 0;
		}
		if(this.acceptedAnnotations != null){
			this.acceptedAnswer = true;
			for (int i = 0; i < this.acceptedAnnotationsCount; i++) {
				this.noProposal = false;
				this.requestor.acceptType(
					this.acceptedAnnotations[i][0],
					this.acceptedAnnotations[i][1],
					this.acceptedAnnotationsModifiers[i],
					false,
					null,
					this.actualSelectionStart,
					this.actualSelectionEnd);
			}
			this.acceptedAnnotations = null;
			this.acceptedAnnotationsModifiers = null;
			this.acceptedAnnotationsCount = 0;
		}
		if(this.acceptedEnums != null){
			this.acceptedAnswer = true;
			for (int i = 0; i < this.acceptedEnumsCount; i++) {
				this.noProposal = false;
				this.requestor.acceptType(
					this.acceptedEnums[i][0],
					this.acceptedEnums[i][1],
					this.acceptedEnumsModifiers[i],
					false,
					null,
					this.actualSelectionStart,
					this.actualSelectionEnd);
			}
			this.acceptedEnums = null;
			this.acceptedEnumsModifiers = null;
			this.acceptedEnumsCount = 0;
		}
	}
	private boolean checkSelection(
			char[] source,
			int selectionStart,
			int selectionEnd) {

		Scanner scanner =
			new Scanner(
				false /*comment*/,
				false /*whitespace*/,
				false /*nls*/,
				this.compilerOptions.sourceLevel,
				this.compilerOptions.complianceLevel,
				null/*taskTag*/,
				null/*taskPriorities*/,
				true /*taskCaseSensitive*/);
		scanner.setSource(source);

		int lastIdentifierStart = -1;
		int lastIdentifierEnd = -1;
		char[] lastIdentifier = null;
		int token;

		if(selectionStart > selectionEnd){
			int end = source.length - 1;

			// compute start position of current line
			int currentPosition = selectionStart - 1;
			int nextCharacterPosition = selectionStart;
			char currentCharacter = ' ';
			try {
				lineLoop: while(currentPosition > 0){

					if(source[currentPosition] == '\\' && source[currentPosition+1] == 'u') {
						int pos = currentPosition + 2;
						int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
						while (source[pos] == 'u') {
							pos++;
						}

						int endOfUnicode = pos + 3;
						if (end < endOfUnicode) {
							if (endOfUnicode < source.length) {
								end = endOfUnicode;
							} else {
								return false; // not enough characters to decode an unicode
							}
						}

						if ((c1 = ScannerHelper.getNumericValue(source[pos++])) > 15
							|| c1 < 0
							|| (c2 = ScannerHelper.getNumericValue(source[pos++])) > 15
							|| c2 < 0
							|| (c3 = ScannerHelper.getNumericValue(source[pos++])) > 15
							|| c3 < 0
							|| (c4 = ScannerHelper.getNumericValue(source[pos++])) > 15
							|| c4 < 0) {
							return false;
						} else {
							currentCharacter = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
							nextCharacterPosition = pos;
						}
					} else {
						currentCharacter = source[currentPosition];
						nextCharacterPosition = currentPosition+1;
					}

					switch(currentCharacter) {
						case '\r':
						case '\n':
						case '/':
						case '"':
						case '\'':
							break lineLoop;
					}
					currentPosition--;
				}
			} catch (ArrayIndexOutOfBoundsException e) {
				return false;
			}

			// compute start and end of the last token
			scanner.resetTo(nextCharacterPosition, end);
			isolateLastName: do {
				try {
					token = scanner.getNextToken();
				} catch (InvalidInputException e) {
					return false;
				}
				switch (token) {
					case TerminalTokens.TokenNamethis:
					case TerminalTokens.TokenNamesuper:
					case TerminalTokens.TokenNameIdentifier:
						if (scanner.startPosition <= selectionStart && selectionStart <= scanner.currentPosition) {
							if (scanner.currentPosition == scanner.eofPosition) {
								int temp = scanner.eofPosition;
								scanner.eofPosition = scanner.source.length;
							 	while(scanner.getNextCharAsJavaIdentifierPart()){/*empty*/}
							 	scanner.eofPosition = temp;
							}
							lastIdentifierStart = scanner.startPosition;
							lastIdentifierEnd = scanner.currentPosition - 1;
							lastIdentifier = scanner.getCurrentTokenSource();
							break isolateLastName;
						}
						break;
				}
			} while (token != TerminalTokens.TokenNameEOF);
		} else {
			scanner.resetTo(selectionStart, selectionEnd);

			boolean expectingIdentifier = true;
			do {
				try {
					token = scanner.getNextToken();
				} catch (InvalidInputException e) {
					return false;
				}
				switch (token) {
					case TerminalTokens.TokenNamethis :
					case TerminalTokens.TokenNamesuper :
					case TerminalTokens.TokenNameIdentifier :
						if (!expectingIdentifier)
							return false;
						lastIdentifier = scanner.getCurrentTokenSource();
						lastIdentifierStart = scanner.startPosition;
						lastIdentifierEnd = scanner.currentPosition - 1;
						if(lastIdentifierEnd > selectionEnd) {
							lastIdentifierEnd = selectionEnd;
							lastIdentifier = CharOperation.subarray(lastIdentifier, 0,lastIdentifierEnd - lastIdentifierStart + 1);
						}
						expectingIdentifier = false;
						break;
					case TerminalTokens.TokenNameDOT :
						if (expectingIdentifier)
							return false;
						expectingIdentifier = true;
						break;
					case TerminalTokens.TokenNameEOF :
						if (expectingIdentifier)
							return false;
						break;
					case TerminalTokens.TokenNameLESS :
						if(!checkTypeArgument(scanner))
							return false;
						break;
					case TerminalTokens.TokenNameAT:
						if(scanner.startPosition != scanner.initialPosition)
							return false;
						break;
					default :
						return false;
				}
			} while (token != TerminalTokens.TokenNameEOF);
		}
		if (lastIdentifierStart > 0) {
			this.actualSelectionStart = lastIdentifierStart;
			this.actualSelectionEnd = lastIdentifierEnd;
			this.selectedIdentifier = lastIdentifier;
			return true;
		}
		return false;
	}
	private boolean checkTypeArgument(Scanner scanner) {
		int depth = 1;
		int token;
		StringBuffer buffer = new StringBuffer();
		do {
			try {
				token = scanner.getNextToken();
			} catch (InvalidInputException e) {
				return false;
			}
			switch(token) {
				case TerminalTokens.TokenNameLESS :
					depth++;
					buffer.append(scanner.getCurrentTokenSource());
					break;
				case TerminalTokens.TokenNameGREATER :
					depth--;
					buffer.append(scanner.getCurrentTokenSource());
					break;
				case TerminalTokens.TokenNameRIGHT_SHIFT :
					depth-=2;
					buffer.append(scanner.getCurrentTokenSource());
					break;
				case TerminalTokens.TokenNameUNSIGNED_RIGHT_SHIFT :
					depth-=3;
					buffer.append(scanner.getCurrentTokenSource());
					break;
				case TerminalTokens.TokenNameextends :
				case TerminalTokens.TokenNamesuper :
					buffer.append(' ');
					buffer.append(scanner.getCurrentTokenSource());
					buffer.append(' ');
					break;
				case TerminalTokens.TokenNameCOMMA :
					if(depth == 1) {
						int length = buffer.length();
						char[] typeRef = new char[length];
						buffer.getChars(0, length, typeRef, 0);
						try {
							Signature.createTypeSignature(typeRef, true);
							buffer = new StringBuffer();
						} catch(IllegalArgumentException e) {
							return false;
						}
					}
					break;
				default :
					buffer.append(scanner.getCurrentTokenSource());
					break;

			}
			if(depth < 0) {
				return false;
			}
		} while (depth != 0 && token != TerminalTokens.TokenNameEOF);

		if(depth == 0) {
			int length = buffer.length() - 1;
			char[] typeRef = new char[length];
			buffer.getChars(0, length, typeRef, 0);
			try {
				Signature.createTypeSignature(typeRef, true);
				return true;
			} catch(IllegalArgumentException e) {
				return false;
			}
		}

		return false;
	}
	
	/*
	 * find all types outside the project scope
	 */
	private void findAllTypes(char[] prefix) {
		try {
			IProgressMonitor progressMonitor = new IProgressMonitor() {
				boolean isCanceled = false;
				public void beginTask(String name, int totalWork) {
					// implements interface method
				}
				public void done() {
					// implements interface method
				}
				public void internalWorked(double work) {
					// implements interface method
				}
				public boolean isCanceled() {
					return this.isCanceled;
				}
				public void setCanceled(boolean value) {
					this.isCanceled = value;
				}
				public void setTaskName(String name) {
					// implements interface method
				}
				public void subTask(String name) {
					// implements interface method
				}
				public void worked(int work) {
					// implements interface method
				}
			};
			
			TypeNameMatchRequestor typeNameMatchRequestor = new TypeNameMatchRequestor() {
				public void acceptTypeNameMatch(TypeNameMatch match) {
					if (SelectionEngine.this.requestor instanceof SelectionRequestor) {
						SelectionEngine.this.noProposal = false;
						((SelectionRequestor)SelectionEngine.this.requestor).acceptType(match.getType());
					}
				}
			};
			
			IJavaSearchScope scope = BasicSearchEngine.createWorkspaceScope();
			
			SelectionTypeNameMatchRequestorWrapper requestorWrapper =
				new SelectionTypeNameMatchRequestorWrapper(
						typeNameMatchRequestor, 
						scope,
						this.unitScope == null ? null : this.unitScope.referenceContext.imports);
			
			org.eclipse.jdt.core.ICompilationUnit[] workingCopies = this.owner == null ? null : JavaModelManager.getJavaModelManager().getWorkingCopies(this.owner, true/*add primary WCs*/);
			
			try {
				new BasicSearchEngine(workingCopies).searchAllTypeNames(
					null,
					SearchPattern.R_EXACT_MATCH,
					prefix,
					SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE,
					IJavaSearchConstants.TYPE,
					scope,
					requestorWrapper,
					IJavaSearchConstants.CANCEL_IF_NOT_READY_TO_SEARCH,
					progressMonitor);
			} catch (OperationCanceledException e) {
				// do nothing
			}
			requestorWrapper.acceptNotImported();
		} catch (JavaModelException e) {
			// do nothing
		}
	}

	public AssistParser getParser() {
		return this.parser;
	}

	/*
	 * Returns whether the given binding is a local/anonymous reference binding, or if its declaring class is
	 * local.
	 */
	private boolean isLocal(ReferenceBinding binding) {
		if(binding instanceof ParameterizedTypeBinding) {
			return isLocal(((ParameterizedTypeBinding)binding).genericType());
		}
		if (!(binding instanceof SourceTypeBinding)) return false;
		if (binding instanceof LocalTypeBinding) return true;
		if (binding instanceof MemberTypeBinding) {
			return isLocal(((MemberTypeBinding)binding).enclosingType);
		}
		return false;
	}

	/**
	 * Ask the engine to compute the selection at the specified position
	 * of the given compilation unit.

	 *  @param sourceUnit org.eclipse.jdt.internal.compiler.env.ICompilationUnit
	 *      the source of the current compilation unit.
	 *
	 *  @param selectionSourceStart int
	 *  @param selectionSourceEnd int
	 *      a range in the source where the selection is.
	 */
	public void select(
		ICompilationUnit sourceUnit,
		int selectionSourceStart,
		int selectionSourceEnd) {

		char[] source = sourceUnit.getContents();

		if(DEBUG) {
			System.out.print("SELECTION IN "); //$NON-NLS-1$
			System.out.print(sourceUnit.getFileName());
			System.out.print(" FROM "); //$NON-NLS-1$
			System.out.print(selectionSourceStart);
			System.out.print(" TO "); //$NON-NLS-1$
			System.out.println(selectionSourceEnd);
			System.out.println("SELECTION - Source :"); //$NON-NLS-1$
			System.out.println(source);
		}
		if (!checkSelection(source, selectionSourceStart, selectionSourceEnd)) {
			return;
		}
		if (DEBUG) {
			System.out.print("SELECTION - Checked : \""); //$NON-NLS-1$
			System.out.print(new String(source, this.actualSelectionStart, this.actualSelectionEnd-this.actualSelectionStart+1));
			System.out.println('"');
		}
		try {
			this.acceptedAnswer = false;
			CompilationResult result = new CompilationResult(sourceUnit, 1, 1, this.compilerOptions.maxProblemsPerUnit);
			CompilationUnitDeclaration parsedUnit =
				this.parser.dietParse(sourceUnit, result, this.actualSelectionStart, this.actualSelectionEnd);

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

				// scan the package & import statements first
				if (parsedUnit.currentPackage instanceof SelectionOnPackageReference) {
					char[][] tokens =
						((SelectionOnPackageReference) parsedUnit.currentPackage).tokens;
					this.noProposal = false;
					this.requestor.acceptPackage(CharOperation.concatWith(tokens, '.'));
					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 SelectionOnImportReference) {
							char[][] tokens = ((SelectionOnImportReference) importReference).tokens;
							this.noProposal = false;
							this.requestor.acceptPackage(CharOperation.concatWith(tokens, '.'));
							this.nameEnvironment.findTypes(CharOperation.concatWith(tokens, '.'), false, false, IJavaSearchConstants.TYPE, this);

							this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
							if ((this.unitScope = parsedUnit.scope) != null) {
								int tokenCount = tokens.length;
								char[] lastToken = tokens[tokenCount - 1];
								char[][] qualifierTokens = CharOperation.subarray(tokens, 0, tokenCount - 1);

								if(qualifierTokens != null && qualifierTokens.length > 0) {
									Binding binding = this.unitScope.getTypeOrPackage(qualifierTokens);
									if(binding != null && binding instanceof ReferenceBinding) {
										ReferenceBinding ref = (ReferenceBinding) binding;
										selectMemberTypeFromImport(parsedUnit, lastToken, ref, importReference.isStatic());
										if(importReference.isStatic()) {
											selectStaticFieldFromStaticImport(parsedUnit, lastToken, ref);
											selectStaticMethodFromStaticImport(parsedUnit, lastToken, ref);
										}
									}
								}
							}

							// accept qualified types only if no unqualified type was accepted
							if(!this.acceptedAnswer) {
								acceptQualifiedTypes();
								if (!this.acceptedAnswer) {
									this.nameEnvironment.findTypes(this.selectedIdentifier, false, false, IJavaSearchConstants.TYPE, this);
									// try with simple type name
									if(!this.acceptedAnswer) {
										acceptQualifiedTypes();
									}
								}
							}
							if(this.noProposal && this.problem != null) {
								this.requestor.acceptError(this.problem);
							}
							return;
						}
					}
				}
				if (parsedUnit.types != null || parsedUnit.isPackageInfo()) {
					if(selectDeclaration(parsedUnit))
						return;
					this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
					if ((this.unitScope = parsedUnit.scope)  != null) {
						try {
							this.lookupEnvironment.completeTypeBindings(parsedUnit, true);
							
							CompilationUnitDeclaration previousUnitBeingCompleted = this.lookupEnvironment.unitBeingCompleted;
							this.lookupEnvironment.unitBeingCompleted = parsedUnit;
							parsedUnit.scope.faultInTypes();
							this.lookupEnvironment.unitBeingCompleted = previousUnitBeingCompleted;
							ASTNode node = null;
							if (parsedUnit.types != null)
								node = parseBlockStatements(parsedUnit, selectionSourceStart);
							if(DEBUG) {
								System.out.println("SELECTION - AST :"); //$NON-NLS-1$
								System.out.println(parsedUnit.toString());
							}
							parsedUnit.resolve();
							if (node != null) {
								selectLocalDeclaration(node);
							}
						} catch (SelectionNodeFound e) {
							if (e.binding != null) {
								if(DEBUG) {
									System.out.println("SELECTION - Selection binding:"); //$NON-NLS-1$
									System.out.println(e.binding.toString());
								}
								// if null then we found a problem in the selection node
								selectFrom(e.binding, parsedUnit, e.isDeclaration);
							}
						}
					}
				}
			}
			// only reaches here if no selection could be derived from the parsed tree
			// thus use the selected source and perform a textual type search
			if (!this.acceptedAnswer) {
				this.nameEnvironment.findTypes(this.selectedIdentifier, false, false, IJavaSearchConstants.TYPE, this);

				// accept qualified types only if no unqualified type was accepted
				if(!this.acceptedAnswer) {
					acceptQualifiedTypes();
					
					// accept types from all the workspace only if no type was found in the project scope
					if (this.noProposal) {
						findAllTypes(this.selectedIdentifier);
					}
				}
			}
			if(this.noProposal && this.problem != null) {
				this.requestor.acceptError(this.problem);
			}
		} catch (IndexOutOfBoundsException e) { // work-around internal failure - 1GEMF6D
			if(DEBUG) {
				System.out.println("Exception caught by SelectionEngine:"); //$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 SelectionEngine:"); //$NON-NLS-1$
				e.printStackTrace(System.out);
			}
		} finally {
			reset(true);
		}
	}

	private void selectMemberTypeFromImport(CompilationUnitDeclaration parsedUnit, char[] lastToken, ReferenceBinding ref, boolean staticOnly) {
		int fieldLength = lastToken.length;
		ReferenceBinding[] memberTypes = ref.memberTypes();
		next : for (int j = 0; j < memberTypes.length; j++) {
			ReferenceBinding memberType = memberTypes[j];

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

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

			if (!CharOperation.equals(lastToken, memberType.sourceName, true))
				continue next;

			selectFrom(memberType, parsedUnit, false);
		}
	}

	private void selectStaticFieldFromStaticImport(CompilationUnitDeclaration parsedUnit, char[] lastToken, ReferenceBinding ref) {
		int fieldLength = lastToken.length;
		FieldBinding[] fields = ref.availableFields();
		next : for (int j = 0; j < fields.length; j++) {
			FieldBinding field = fields[j];

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

			if (field.isSynthetic())
				continue next;

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

			if (!CharOperation.equals(lastToken, field.name, true))
				continue next;

			selectFrom(field, parsedUnit, false);
		}
	}

	private void selectStaticMethodFromStaticImport(CompilationUnitDeclaration parsedUnit, char[] lastToken, ReferenceBinding ref) {
		int methodLength = lastToken.length;
		MethodBinding[] methods = ref.availableMethods();
		next : for (int j = 0; j < methods.length; j++) {
			MethodBinding method = methods[j];

			if (method.isSynthetic()) continue next;

			if (method.isDefaultAbstract())	continue next;

			if (method.isConstructor()) continue next;

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

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

			if (!CharOperation.equals(lastToken, method.selector, true))
				continue next;

			selectFrom(method, parsedUnit, false);
		}
	}

	private void selectFrom(Binding binding, CompilationUnitDeclaration parsedUnit, boolean isDeclaration) {
		if(binding instanceof TypeVariableBinding) {
			TypeVariableBinding typeVariableBinding = (TypeVariableBinding) binding;
			Binding enclosingElement = typeVariableBinding.declaringElement;
			this.noProposal = false;

			if(enclosingElement instanceof SourceTypeBinding) {
				SourceTypeBinding enclosingType = (SourceTypeBinding) enclosingElement;
				if (isLocal(enclosingType) && this.requestor instanceof SelectionRequestor) {
					((SelectionRequestor)this.requestor).acceptLocalTypeParameter(typeVariableBinding);
				} else {
					this.requestor.acceptTypeParameter(
						enclosingType.qualifiedPackageName(),
						enclosingType.qualifiedSourceName(),
						typeVariableBinding.sourceName(),
						false,
						this.actualSelectionStart,
						this.actualSelectionEnd);
				}
			} else if(enclosingElement instanceof MethodBinding) {
				MethodBinding enclosingMethod = (MethodBinding) enclosingElement;
				if (isLocal(enclosingMethod.declaringClass) && this.requestor instanceof SelectionRequestor) {
					((SelectionRequestor)this.requestor).acceptLocalMethodTypeParameter(typeVariableBinding);
				} else {
					this.requestor.acceptMethodTypeParameter(
						enclosingMethod.declaringClass.qualifiedPackageName(),
						enclosingMethod.declaringClass.qualifiedSourceName(),
						enclosingMethod.isConstructor()
								? enclosingMethod.declaringClass.sourceName()
								: enclosingMethod.selector,
						enclosingMethod.sourceStart(),
						enclosingMethod.sourceEnd(),
						typeVariableBinding.sourceName(),
						false,
						this.actualSelectionStart,
						this.actualSelectionEnd);
				}
			}
			this.acceptedAnswer = true;
		} else if (binding instanceof ReferenceBinding) {
			ReferenceBinding typeBinding = (ReferenceBinding) binding;
			if(typeBinding instanceof ProblemReferenceBinding) {
				TypeBinding closestMatch = typeBinding.closestMatch();
				if (closestMatch instanceof ReferenceBinding) {
					typeBinding = (ReferenceBinding) closestMatch;
				} else {
					typeBinding = null;
				}
			}
			if (typeBinding == null) return;
			if (isLocal(typeBinding) && this.requestor instanceof SelectionRequestor) {
				this.noProposal = false;
				((SelectionRequestor)this.requestor).acceptLocalType(typeBinding);
			} else {
				this.noProposal = false;

				this.requestor.acceptType(
					typeBinding.qualifiedPackageName(),
					typeBinding.qualifiedSourceName(),
					typeBinding.modifiers,
					false,
					typeBinding.computeUniqueKey(),
					this.actualSelectionStart,
					this.actualSelectionEnd);
			}
			this.acceptedAnswer = true;
		} else if (binding instanceof MethodBinding) {
			MethodBinding methodBinding = getCorrectMethodBinding((MethodBinding) binding);
			this.noProposal = false;

			boolean isValuesOrValueOf = false;
			if(binding instanceof SyntheticMethodBinding) {
				SyntheticMethodBinding syntheticMethodBinding = (SyntheticMethodBinding) binding;
				if(syntheticMethodBinding.purpose  == SyntheticMethodBinding.EnumValues
						|| syntheticMethodBinding.purpose  == SyntheticMethodBinding.EnumValueOf) {
					isValuesOrValueOf =  true;
				}
			}

			if(!isValuesOrValueOf && !methodBinding.isSynthetic()) {
				TypeBinding[] parameterTypes = methodBinding.original().parameters;
				int length = parameterTypes.length;
				char[][] parameterPackageNames = new char[length][];
				char[][] parameterTypeNames = new char[length][];
				String[] parameterSignatures = new String[length];
				for (int i = 0; i < length; i++) {
					parameterPackageNames[i] = parameterTypes[i].qualifiedPackageName();
					parameterTypeNames[i] = parameterTypes[i].qualifiedSourceName();
					parameterSignatures[i] = new String(getSignature(parameterTypes[i])).replace('/', '.');
				}

				TypeVariableBinding[] typeVariables = methodBinding.original().typeVariables;
				length = typeVariables == null ? 0 : typeVariables.length;
				char[][] typeParameterNames = new char[length][];
				char[][][] typeParameterBoundNames = new char[length][][];
				for (int i = 0; i < length; i++) {
					TypeVariableBinding typeVariable = typeVariables[i];
					typeParameterNames[i] = typeVariable.sourceName;
					if (typeVariable.firstBound == null) {
						typeParameterBoundNames[i] = new char[0][];
					} else if (typeVariable.firstBound == typeVariable.superclass) {
						int boundCount = 1 + (typeVariable.superInterfaces == null ? 0 : typeVariable.superInterfaces.length);
						typeParameterBoundNames[i] = new char[boundCount][];
						typeParameterBoundNames[i][0] = typeVariable.superclass.sourceName;
						for (int j = 1; j < boundCount; j++) {
							typeParameterBoundNames[i][j] = typeVariables[i].superInterfaces[j - 1].sourceName;
						}
					} else {
						int boundCount = typeVariable.superInterfaces == null ? 0 : typeVariable.superInterfaces.length;
						typeParameterBoundNames[i] = new char[boundCount][];
						for (int j = 0; j < boundCount; j++) {
							typeParameterBoundNames[i][j] = typeVariables[i].superInterfaces[j].sourceName;
						}
					}
				}

				ReferenceBinding declaringClass = methodBinding.declaringClass;
				if (isLocal(declaringClass) && this.requestor instanceof SelectionRequestor) {
					((SelectionRequestor)this.requestor).acceptLocalMethod(methodBinding);
				} else {
					this.requestor.acceptMethod(
						declaringClass.qualifiedPackageName(),
						declaringClass.qualifiedSourceName(),
						declaringClass.enclosingType() == null ? null : new String(getSignature(declaringClass.enclosingType())),
						methodBinding.isConstructor()
							? declaringClass.sourceName()
							: methodBinding.selector,
						parameterPackageNames,
						parameterTypeNames,
						parameterSignatures,
						typeParameterNames,
						typeParameterBoundNames,
						methodBinding.isConstructor(),
						isDeclaration,
						methodBinding.computeUniqueKey(),
						this.actualSelectionStart,
						this.actualSelectionEnd);
				}
			}
			this.acceptedAnswer = true;
		} else if (binding instanceof FieldBinding) {
			FieldBinding fieldBinding = (FieldBinding) binding;
			ReferenceBinding declaringClass = fieldBinding.declaringClass;
			if (declaringClass != null) { // arraylength
				this.noProposal = false;
				if (isLocal(declaringClass) && this.requestor instanceof SelectionRequestor) {
					((SelectionRequestor)this.requestor).acceptLocalField(fieldBinding);
				} else {
					// if the binding is a problem field binding, we want to make sure
					// we can retrieve the closestMatch if the problem reason is NotVisible
					FieldBinding currentFieldBinding = fieldBinding;
					while (currentFieldBinding instanceof ProblemFieldBinding) {
						ProblemFieldBinding problemFieldBinding = (ProblemFieldBinding) currentFieldBinding;
						if (problemFieldBinding.problemId() == ProblemReasons.NotVisible) {
							currentFieldBinding = problemFieldBinding.closestMatch;
						} else {
							currentFieldBinding = null;
						}
					}
					char[] fieldName = null;
					char[] key = null;
					if (currentFieldBinding != null) {
						fieldName = currentFieldBinding.name;
						key = currentFieldBinding.computeUniqueKey();
					} else {
						fieldName = fieldBinding.name;
						key = fieldBinding.computeUniqueKey();
					}
					this.requestor.acceptField(
						declaringClass.qualifiedPackageName(),
						declaringClass.qualifiedSourceName(),
						fieldName,
						false,
						key,
						this.actualSelectionStart,
						this.actualSelectionEnd);
				}
				this.acceptedAnswer = true;
			}
		} else if (binding instanceof LocalVariableBinding) {
			if (this.requestor instanceof SelectionRequestor) {
				((SelectionRequestor)this.requestor).acceptLocalVariable((LocalVariableBinding)binding);
				this.acceptedAnswer = true;
			} else {
				// open on the type of the variable
				selectFrom(((LocalVariableBinding) binding).type, parsedUnit, false);
			}
		} else if (binding instanceof ArrayBinding) {
			selectFrom(((ArrayBinding) binding).leafComponentType, parsedUnit, false);
			// open on the type of the array
		} else if (binding instanceof PackageBinding) {
			PackageBinding packageBinding = (PackageBinding) binding;
			this.noProposal = false;
			this.requestor.acceptPackage(packageBinding.readableName());
			this.acceptedAnswer = true;
		} else if(binding instanceof BaseTypeBinding) {
			this.acceptedAnswer = true;
		}
	}
	/*
	 * Checks if a local declaration got selected in this method/initializer/field.
	 */
	private void selectLocalDeclaration(ASTNode node) {
		// the selected identifier is not identical to the parser one (equals but not identical),
		// for traversing the parse tree, the parser assist identifier is necessary for identitiy checks
		final char[] assistIdentifier = getParser().assistIdentifier();
		if (assistIdentifier == null) return;

		class Visitor extends ASTVisitor {
			public boolean visit(ConstructorDeclaration constructorDeclaration, ClassScope scope) {
				if (constructorDeclaration.selector == assistIdentifier){
					if (constructorDeclaration.binding != null) {
						throw new SelectionNodeFound(constructorDeclaration.binding);
					} else {
						if (constructorDeclaration.scope != null) {
							throw new SelectionNodeFound(new MethodBinding(constructorDeclaration.modifiers, constructorDeclaration.selector, null, null, null, constructorDeclaration.scope.referenceType().binding));
						}
					}
				}
				return true;
			}
			public boolean visit(FieldDeclaration fieldDeclaration, MethodScope scope) {
				if (fieldDeclaration.name == assistIdentifier){
					throw new SelectionNodeFound(fieldDeclaration.binding);
				}
				return true;
			}
			public boolean visit(TypeDeclaration localTypeDeclaration, BlockScope scope) {
				if (localTypeDeclaration.name == assistIdentifier) {
					throw new SelectionNodeFound(localTypeDeclaration.binding);
				}
				return true;
			}
			public boolean visit(TypeDeclaration memberTypeDeclaration, ClassScope scope) {
				if (memberTypeDeclaration.name == assistIdentifier) {
					throw new SelectionNodeFound(memberTypeDeclaration.binding);
				}
				return true;
			}
			public boolean visit(MethodDeclaration methodDeclaration, ClassScope scope) {
				if (methodDeclaration.selector == assistIdentifier){
					if (methodDeclaration.binding != null) {
						throw new SelectionNodeFound(methodDeclaration.binding);
					} else {
						if (methodDeclaration.scope != null) {
							throw new SelectionNodeFound(new MethodBinding(methodDeclaration.modifiers, methodDeclaration.selector, null, null, null, methodDeclaration.scope.referenceType().binding));
						}
					}
				}
				return true;
			}
			public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope scope) {
				if (typeDeclaration.name == assistIdentifier) {
					throw new SelectionNodeFound(typeDeclaration.binding);
				}
				return true;
			}
			public boolean visit(TypeParameter typeParameter, BlockScope scope) {
				if (typeParameter.name == assistIdentifier) {
					throw new SelectionNodeFound(typeParameter.binding);
				}
				return true;
			}
			public boolean visit(TypeParameter typeParameter, ClassScope scope) {
				if (typeParameter.name == assistIdentifier) {
					throw new SelectionNodeFound(typeParameter.binding);
				}
				return true;
			}
		}

		if (node instanceof AbstractMethodDeclaration) {
			((AbstractMethodDeclaration)node).traverse(new Visitor(), (ClassScope)null);
		} else {
			((FieldDeclaration)node).traverse(new Visitor(), (MethodScope)null);
		}
	}

	/**
	 * Asks the engine to compute the selection of the given type
	 * from the given context
	 *
	 *  @param typeName char[]
	 *      a type name which is to be resolved in the context of a compilation unit.
	 *		NOTE: the type name is supposed to be correctly reduced (no whitespaces, no unicodes left)
	 *
	 *  @param context org.eclipse.jdt.core.IType
	 *      the context in which code assist is invoked.
	 */
	public void selectType(char[] typeName, IType context) throws JavaModelException {
		try {
			this.acceptedAnswer = false;

			// only the type erasure are returned by IType.resolvedType(...)
			if (CharOperation.indexOf('<', typeName) != -1) {
				char[] typeSig = Signature.createCharArrayTypeSignature(typeName, false/*not resolved*/);
				typeSig = Signature.getTypeErasure(typeSig);
				typeName = Signature.toCharArray(typeSig);
			}

			// find the outer most type
			IType outerType = context;
			IType parent = context.getDeclaringType();
			while (parent != null) {
				outerType = parent;
				parent = parent.getDeclaringType();
			}

			// compute parse tree for this most outer type
			CompilationUnitDeclaration parsedUnit = null;
			TypeDeclaration typeDeclaration = null;
			org.eclipse.jdt.core.ICompilationUnit cu = context.getCompilationUnit();
			if (cu != null) {
			 	IType[] topLevelTypes = cu.getTypes();
			 	int length = topLevelTypes.length;
			 	SourceTypeElementInfo[] topLevelInfos = new SourceTypeElementInfo[length];
			 	for (int i = 0; i < length; i++) {
					topLevelInfos[i] = (SourceTypeElementInfo) ((SourceType)topLevelTypes[i]).getElementInfo();
				}
				ISourceType outerTypeInfo = (ISourceType) ((SourceType) outerType).getElementInfo();
				CompilationResult result = new CompilationResult(outerTypeInfo.getFileName(), 1, 1, this.compilerOptions.maxProblemsPerUnit);
				int flags = SourceTypeConverter.FIELD_AND_METHOD | SourceTypeConverter.MEMBER_TYPE;
				if (context.isAnonymous() || context.isLocal())
					flags |= SourceTypeConverter.LOCAL_TYPE;
				parsedUnit =
					SourceTypeConverter.buildCompilationUnit(
							topLevelInfos,
							flags,
							this.parser.problemReporter(),
							result);
				if (parsedUnit != null && parsedUnit.types != null) {
					if(DEBUG) {
						System.out.println("SELECTION - Diet AST :"); //$NON-NLS-1$
						System.out.println(parsedUnit.toString());
					}
					// find the type declaration that corresponds to the original source type
					typeDeclaration = new ASTNodeFinder(parsedUnit).findType(context);
				}
			} else { // binary type
				ClassFile classFile = (ClassFile) context.getClassFile();
				ClassFileReader reader = (ClassFileReader) classFile.getBinaryTypeInfo((IFile) classFile.resource(), false/*don't fully initialize so as to keep constant pool (used below)*/);
				CompilationResult result = new CompilationResult(reader.getFileName(), 1, 1, this.compilerOptions.maxProblemsPerUnit);
				parsedUnit = new CompilationUnitDeclaration(this.parser.problemReporter(), result, 0);
				HashSetOfCharArrayArray typeNames = new HashSetOfCharArrayArray();

				BinaryTypeConverter converter = new BinaryTypeConverter(this.parser.problemReporter(), result, typeNames);
				typeDeclaration = converter.buildTypeDeclaration(context, parsedUnit);
				parsedUnit.imports = converter.buildImports(reader);
			}

			if (typeDeclaration != null) {

				// add fake field with the type we're looking for
				// note: since we didn't ask for fields above, there is no field defined yet
				FieldDeclaration field = new FieldDeclaration();
				int dot;
				if ((dot = CharOperation.lastIndexOf('.', typeName)) == -1) {
					this.selectedIdentifier = typeName;
					field.type = new SelectionOnSingleTypeReference(typeName, -1);
					// position not used
				} else {
					char[][] previousIdentifiers = CharOperation.splitOn('.', typeName, 0, dot);
					char[] selectionIdentifier =
						CharOperation.subarray(typeName, dot + 1, typeName.length);
					this.selectedIdentifier = selectionIdentifier;
					field.type =
						new SelectionOnQualifiedTypeReference(
							previousIdentifiers,
							selectionIdentifier,
							new long[previousIdentifiers.length + 1]);
				}
				field.name = "<fakeField>".toCharArray(); //$NON-NLS-1$
				typeDeclaration.fields = new FieldDeclaration[] { field };

				// build bindings
				this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
				if ((this.unitScope = parsedUnit.scope) != null) {
					try {
						// build fields
						// note: this builds fields only in the parsed unit (the buildFieldsAndMethods flag is not passed along)
						this.lookupEnvironment.completeTypeBindings(parsedUnit, true);

						// resolve
						parsedUnit.scope.faultInTypes();
						parsedUnit.resolve();
					} catch (SelectionNodeFound e) {
						if (e.binding != null) {
							if(DEBUG) {
								System.out.println("SELECTION - Selection binding :"); //$NON-NLS-1$
								System.out.println(e.binding.toString());
							}
							// if null then we found a problem in the selection node
							selectFrom(e.binding, parsedUnit, e.isDeclaration);
						}
					}
				}
			}
			if(this.noProposal && this.problem != null) {
				this.requestor.acceptError(this.problem);
			}
		} catch (AbortCompilation e) { // ignore this exception for now since it typically means we cannot find java.lang.Object
		} finally {
			reset(true);
		}
	}

	// Check if a declaration got selected in this unit
	private boolean selectDeclaration(CompilationUnitDeclaration compilationUnit){

		// the selected identifier is not identical to the parser one (equals but not identical),
		// for traversing the parse tree, the parser assist identifier is necessary for identitiy checks
		char[] assistIdentifier = getParser().assistIdentifier();
		if (assistIdentifier == null) return false;

		ImportReference currentPackage = compilationUnit.currentPackage;
		char[] packageName = currentPackage == null ? CharOperation.NO_CHAR : CharOperation.concatWith(currentPackage.tokens, '.');
		// iterate over the types
		TypeDeclaration[] types = compilationUnit.types;
		for (int i = 0, length = types == null ? 0 : types.length; i < length; i++){
			if(selectDeclaration(types[i], assistIdentifier, packageName))
				return true;
		}
		return false;
	}

	// Check if a declaration got selected in this type
	private boolean selectDeclaration(TypeDeclaration typeDeclaration, char[] assistIdentifier, char[] packageName){

		if (typeDeclaration.name == assistIdentifier){
			char[] qualifiedSourceName = null;

			TypeDeclaration enclosingType = typeDeclaration;
			while(enclosingType != null) {
				qualifiedSourceName = CharOperation.concat(enclosingType.name, qualifiedSourceName, '.');
				enclosingType = enclosingType.enclosingType;
			}
			char[] uniqueKey = typeDeclaration.binding != null ? typeDeclaration.binding.computeUniqueKey() : null;

			this.requestor.acceptType(
				packageName,
				qualifiedSourceName,
				typeDeclaration.modifiers,
				true,
				uniqueKey,
				this.actualSelectionStart,
				this.actualSelectionEnd);

			this.noProposal = false;
			return true;
		}
		TypeDeclaration[] memberTypes = typeDeclaration.memberTypes;
		for (int i = 0, length = memberTypes == null ? 0 : memberTypes.length; i < length; i++){
			if(selectDeclaration(memberTypes[i], assistIdentifier, packageName))
				return true;
		}
		FieldDeclaration[] fields = typeDeclaration.fields;
		for (int i = 0, length = fields == null ? 0 : fields.length; i < length; i++){
			if (fields[i].name == assistIdentifier){
				char[] qualifiedSourceName = null;

				TypeDeclaration enclosingType = typeDeclaration;
				while(enclosingType != null) {
					qualifiedSourceName = CharOperation.concat(enclosingType.name, qualifiedSourceName, '.');
					enclosingType = enclosingType.enclosingType;
				}
				FieldDeclaration field = fields[i];
				this.requestor.acceptField(
					packageName,
					qualifiedSourceName,
					field.name,
					true,
					field.binding != null ? field.binding.computeUniqueKey() : null,
					this.actualSelectionStart,
					this.actualSelectionEnd);

				this.noProposal = false;
				return true;
			}
		}
		AbstractMethodDeclaration[] methods = typeDeclaration.methods;
		for (int i = 0, length = methods == null ? 0 : methods.length; i < length; i++){
			AbstractMethodDeclaration method = methods[i];

			if (method.selector == assistIdentifier){
				char[] qualifiedSourceName = null;

				TypeDeclaration enclosingType = typeDeclaration;
				while(enclosingType != null) {
					qualifiedSourceName = CharOperation.concat(enclosingType.name, qualifiedSourceName, '.');
					enclosingType = enclosingType.enclosingType;
				}

				this.requestor.acceptMethod(
					packageName,
					qualifiedSourceName,
					null, // SelectionRequestor does not need of declaring type signature for method declaration
					method.selector,
					null, // SelectionRequestor does not need of parameters type for method declaration
					null, // SelectionRequestor does not need of parameters type for method declaration
					null, // SelectionRequestor does not need of parameters type for method declaration
					null, // SelectionRequestor does not need of type parameters name for method declaration
					null, // SelectionRequestor does not need of type parameters bounds for method declaration
					method.isConstructor(),
					true,
					method.binding != null ? method.binding.computeUniqueKey() : null,
					this.actualSelectionStart,
					this.actualSelectionEnd);

				this.noProposal = false;
				return true;
			}

			TypeParameter[] methodTypeParameters = method.typeParameters();
			for (int j = 0, length2 = methodTypeParameters == null ? 0 : methodTypeParameters.length; j < length2; j++){
				TypeParameter methodTypeParameter = methodTypeParameters[j];

				if(methodTypeParameter.name == assistIdentifier) {
					char[] qualifiedSourceName = null;

					TypeDeclaration enclosingType = typeDeclaration;
					while(enclosingType != null) {
						qualifiedSourceName = CharOperation.concat(enclosingType.name, qualifiedSourceName, '.');
						enclosingType = enclosingType.enclosingType;
					}

					this.requestor.acceptMethodTypeParameter(
						packageName,
						qualifiedSourceName,
						method.selector,
						method.sourceStart,
						method.sourceEnd,
						methodTypeParameter.name,
						true,
						this.actualSelectionStart,
						this.actualSelectionEnd);

					this.noProposal = false;
					return true;
				}
			}
		}

		TypeParameter[] typeParameters = typeDeclaration.typeParameters;
		for (int i = 0, length = typeParameters == null ? 0 : typeParameters.length; i < length; i++){
			TypeParameter typeParameter = typeParameters[i];
			if(typeParameter.name == assistIdentifier) {
				char[] qualifiedSourceName = null;

				TypeDeclaration enclosingType = typeDeclaration;
				while(enclosingType != null) {
					qualifiedSourceName = CharOperation.concat(enclosingType.name, qualifiedSourceName, '.');
					enclosingType = enclosingType.enclosingType;
				}

				this.requestor.acceptTypeParameter(
					packageName,
					qualifiedSourceName,
					typeParameter.name,
					true,
					this.actualSelectionStart,
					this.actualSelectionEnd);

				this.noProposal = false;
				return true;
			}
		}

		return false;
	}
	
	/*
	 * Returns the correct method binding according to whether the selection is on the method declaration
	 * or on the inheritDoc tag in its javadoc.
	 */
	private MethodBinding getCorrectMethodBinding(MethodBinding binding) {
		if (this.parser.javadocParser instanceof SelectionJavadocParser) {
			if (((SelectionJavadocParser)this.parser.javadocParser).inheritDocTagSelected){
				try {
					Object res = findMethodWithAttachedDocInHierarchy(binding);
					if (res instanceof MethodBinding) {
						return (MethodBinding) res;
					}
				} catch (JavaModelException e) {
					return null;
				}
			}
		}
		return binding;
	}
	
	protected MethodBinding findOverriddenMethodInType(ReferenceBinding overriddenType, MethodBinding overriding) throws JavaModelException {
		if (overriddenType == null)
			return null;
		MethodBinding[] overriddenMethods= overriddenType.availableMethods();
		LookupEnvironment lookupEnv = this.lookupEnvironment;
		if (lookupEnv != null && overriddenMethods != null) {
			for (int i= 0; i < overriddenMethods.length; i++) {
				if (lookupEnv.methodVerifier().isMethodSubsignature(overriding, overriddenMethods[i])) {
					return overriddenMethods[i];
				}
			}
		}
		return null;
	}
	
	private Object findMethodWithAttachedDocInHierarchy(final MethodBinding method) throws JavaModelException {
		ReferenceBinding type= method.declaringClass;
		final SelectionRequestor requestor1 = (SelectionRequestor) this.requestor;
		return new InheritDocVisitor() {
			public Object visit(ReferenceBinding currType) throws JavaModelException {
				MethodBinding overridden =  findOverriddenMethodInType(currType, method);
				if (overridden == null)
					return InheritDocVisitor.CONTINUE;
				TypeBinding args[] = overridden.parameters;
				String names[] = new String[args.length];
				for (int i = 0; i < args.length; i++) {
					names[i] = Signature.createTypeSignature(args[i].sourceName(), false);
				}
				IMember member = (IMember) requestor1.findMethodFromBinding(overridden, names, overridden.declaringClass);
				if (member == null)
					return InheritDocVisitor.CONTINUE;
				if (member.getAttachedJavadoc(null) != null ) {  
					// for binary methods with attached javadoc and no source attached
					return overridden;
				}
				IOpenable openable = member.getOpenable();
				if (openable == null)
					return InheritDocVisitor.CONTINUE;
				IBuffer buf= openable.getBuffer();
				if (buf == null) {
					// no source attachment found. This method maybe the one. Stop.
					return InheritDocVisitor.STOP_BRANCH;
				}

				ISourceRange javadocRange= member.getJavadocRange();
				if (javadocRange == null)
					return InheritDocVisitor.CONTINUE;	// this method doesn't have javadoc, continue to look.
				String rawJavadoc= buf.getText(javadocRange.getOffset(), javadocRange.getLength());
				if (rawJavadoc != null) {
					return overridden;
				}
				return InheritDocVisitor.CONTINUE;
			}
		}.visitInheritDoc(type);
	}
	
	/**
	 * Implements the "Algorithm for Inheriting Method Comments" as specified for
	 * <a href="http://java.sun.com/j2se/1.4.2/docs/tooldocs/solaris/javadoc.html#inheritingcomments">1.4.2</a>,
	 * <a href="http://java.sun.com/j2se/1.5.0/docs/tooldocs/windows/javadoc.html#inheritingcomments">1.5</a>, and
	 * <a href="http://java.sun.com/javase/6/docs/technotes/tools/windows/javadoc.html#inheritingcomments">1.6</a>.
	 *
	 * <p>
	 * Unfortunately, the implementation is broken in Javadoc implementations since 1.5, see
	 * <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6376959">Sun's bug</a>.
	 * </p>
	 *
	 * <p>
	 * We adhere to the spec.
	 * </p>
	 */
	static abstract class InheritDocVisitor {
		public static final Object STOP_BRANCH= new Object() {
			public String toString() { return "STOP_BRANCH"; } //$NON-NLS-1$
		};
		public static final Object CONTINUE= new Object() {
			public String toString() { return "CONTINUE"; } //$NON-NLS-1$
		};

		/**
		 * Visits a type and decides how the visitor should proceed.
		 *
		 * @param currType the current type
		 * @return <ul>
		 *         <li>{@link #STOP_BRANCH} to indicate that no Javadoc has been found and visiting
		 *         super types should stop here</li>
		 *         <li>{@link #CONTINUE} to indicate that no Javadoc has been found and visiting
		 *         super types should continue</li>
		 *         <li>an {@link Object} or <code>null</code>, to indicate that visiting should be
		 *         cancelled immediately. The returned value is the result of
		 *         {@link #visitInheritDoc(ReferenceBinding)}</li>
		 *         </ul>
		 * @throws JavaModelException unexpected problem
		 * @see #visitInheritDoc(ReferenceBinding)
		 */
		public abstract Object visit(ReferenceBinding currType) throws JavaModelException;

		/**
		 * Visits the super types of the given <code>currentType</code>.
		 *
		 * @param currentType the starting type
		 * @return the result from a call to {@link #visit(ReferenceBinding)}, or <code>null</code> if none of
		 *         the calls returned a result
		 * @throws JavaModelException unexpected problem
		 */
		public Object visitInheritDoc(ReferenceBinding currentType) throws JavaModelException {
			ArrayList visited= new ArrayList();
			visited.add(currentType);
			Object result= visitInheritDocInterfaces(visited, currentType);
			if (result != InheritDocVisitor.CONTINUE)
				return result;

			ReferenceBinding superClass= currentType.superclass();

			while (superClass != null && ! visited.contains(superClass)) {
				result= visit(superClass);
				if (result == InheritDocVisitor.STOP_BRANCH) {
					return null;
				} else if (result == InheritDocVisitor.CONTINUE) {
					visited.add(superClass);
					result= visitInheritDocInterfaces(visited, superClass);
					if (result != InheritDocVisitor.CONTINUE)
						return result;
					else
						superClass= superClass.superclass();
				} else {
					return result;
				}
			}

			return null;
		}

		/**
		 * Visits the super interfaces of the given type in the given hierarchy, thereby skipping already visited types.
		 * 
		 * @param visited set of visited types
		 * @param currentType type whose super interfaces should be visited
		 * @return the result, or {@link #CONTINUE} if no result has been found
		 * @throws JavaModelException unexpected problem
		 */
		private Object visitInheritDocInterfaces(ArrayList visited, ReferenceBinding currentType) throws JavaModelException {
			ArrayList toVisitChildren= new ArrayList();
			ReferenceBinding[] superInterfaces= currentType.superInterfaces();
			for (int i= 0; i < superInterfaces.length; i++) {
				ReferenceBinding superInterface= superInterfaces[i];
				if (visited.contains(superInterface))
					continue;
				visited.add(superInterface);
				Object result= visit(superInterface);
				if (result == InheritDocVisitor.STOP_BRANCH) {
					//skip
				} else if (result == InheritDocVisitor.CONTINUE) {
					toVisitChildren.add(superInterface);
				} else {
					return result;
				}
			}
			for (Iterator iter= toVisitChildren.iterator(); iter.hasNext(); ) {
				ReferenceBinding child= (ReferenceBinding) iter.next();
				Object result= visitInheritDocInterfaces(visited, child);
				if (result != InheritDocVisitor.CONTINUE)
					return result;
			}
			return InheritDocVisitor.CONTINUE;
		}
	}
}
