JDT codeassist module, nothing changed yet
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / codeassist / CompletionEngine.java
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/codeassist/CompletionEngine.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/codeassist/CompletionEngine.java
new file mode 100644 (file)
index 0000000..8d4ed79
--- /dev/null
@@ -0,0 +1,2702 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2001, 2002 International Business Machines Corp. and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v0.5 
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ ******************************************************************************/
+package net.sourceforge.phpdt.internal.codeassist;
+
+import java.util.*;
+
+import net.sourceforge.phpdt.core.compiler.InvalidInputException;
+import net.sourceforge.phpdt.internal.compiler.*;
+import net.sourceforge.phpdt.internal.compiler.env.*;
+
+import net.sourceforge.phpdt.internal.codeassist.impl.*;
+import net.sourceforge.phpdt.core.ICompletionRequestor;
+import net.sourceforge.phpdt.core.IType;
+//import net.sourceforge.phpdt.core.JavaCore;
+//import net.sourceforge.phpdt.core.JavaModelException;
+import net.sourceforge.phpdt.core.compiler.*;
+import net.sourceforge.phpdt.core.compiler.IProblem;
+import net.sourceforge.phpdt.internal.codeassist.complete.*;
+
+import net.sourceforge.phpdt.internal.compiler.ast.*;
+import net.sourceforge.phpdt.internal.compiler.lookup.*;
+import net.sourceforge.phpdt.internal.compiler.parser.*;
+import net.sourceforge.phpdt.internal.compiler.problem.*;
+import net.sourceforge.phpdt.internal.compiler.util.*;
+import net.sourceforge.phpdt.internal.core.BasicCompilationUnit;
+import net.sourceforge.phpdt.internal.core.TypeConverter;
+import net.sourceforge.phpdt.internal.compiler.impl.*;
+
+/**
+ * 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 , ITerminalSymbols , RelevanceConstants {
+       
+       public static boolean DEBUG = 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[] { ';' };
+       TypeBinding[] expectedTypes;
+       
+       boolean assistNodeIsClass;
+       boolean assistNodeIsException;
+       boolean assistNodeIsInterface;
+       
+       CompletionParser parser;
+       ICompletionRequestor requestor;
+       ProblemReporter problemReporter;
+       char[] source;
+       char[] token;
+       boolean resolvingImports = false;
+       boolean insideQualifiedReference = false;
+       int startPosition, actualCompletionPosition, endPosition, offset;
+       HashtableOfObject knownPkgs = new HashtableOfObject(10);
+       HashtableOfObject knownTypes = new HashtableOfObject(10);
+       Scanner nameScanner;
+
+       /*
+               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 char[][] baseTypes = new char[][] { 
+               "boolean".toCharArray(), //$NON-NLS-1$
+               "byte".toCharArray(), //$NON-NLS-1$
+               "char".toCharArray(), //$NON-NLS-1$
+               "double".toCharArray(), //$NON-NLS-1$
+               "float".toCharArray(), //$NON-NLS-1$
+               "int".toCharArray(), //$NON-NLS-1$
+               "long".toCharArray(), //$NON-NLS-1$
+               "short".toCharArray(), //$NON-NLS-1$
+               "void".toCharArray(), //$NON-NLS-1$
+       };
+               
+       static final char[] classField = "class".toCharArray();  //$NON-NLS-1$
+       static final char[] lengthField = "length".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 boolean isSuperAccess(){ return false; }
+               public boolean isTypeAccess(){ return false; }
+               public void setActualReceiverType(ReferenceBinding receiverType) {}
+               public void setDepth(int depth){}
+               public void setFieldIndex(int depth){}
+       };
+
+       /**
+        * 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 net.sourceforge.phpdt.internal.codeassist.ISearchableNameEnvironment
+        *      used to resolve type/package references and search for types/packages
+        *      based on partial names.
+        *
+        *  @param requestor net.sourceforge.phpdt.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(
+               ISearchableNameEnvironment nameEnvironment,
+               ICompletionRequestor requestor,
+               Map settings) {
+
+               super(settings);
+               this.requestor = requestor;
+               this.nameEnvironment = nameEnvironment;
+
+               problemReporter = new ProblemReporter(
+                               DefaultErrorHandlingPolicies.proceedWithAllProblems(),
+                               this.compilerOptions,
+                               new DefaultProblemFactory(Locale.getDefault()) {
+                                       public void record(IProblem problem, CompilationResult unitResult, ReferenceContext referenceContext) {
+                                               if (problem.isError() && (problem.getID() & IProblem.Syntax) != 0) {
+                                                       CompletionEngine.this.requestor.acceptError(problem);
+                                               }
+                                       }
+                               });
+               this.parser =
+                       new CompletionParser(problemReporter, this.compilerOptions.assertMode);
+               this.lookupEnvironment =
+                       new LookupEnvironment(this, this.compilerOptions, problemReporter, nameEnvironment);
+               this.nameScanner =
+                       new Scanner(false, false, false, this.compilerOptions.assertMode);
+       }
+
+       /**
+        * One result of the search consists of a new class.
+        *
+        * 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.M".
+        *    The default package is represented by an empty array.
+        */
+       public void acceptClass(char[] packageName, char[] className, int modifiers) {
+
+               char[] fullyQualifiedName = CharOperation.concat(packageName, className, '.');
+               char[] completionName = fullyQualifiedName;
+               
+               if (this.knownTypes.containsKey(completionName)) return;
+
+               this.knownTypes.put(completionName, this);
+               
+               int relevance = R_DEFAULT;
+               if (resolvingImports) {
+                       completionName = CharOperation.concat(completionName, SEMICOLON);
+                       relevance += computeRelevanceForCaseMatching(token, fullyQualifiedName);
+               } else {
+                       if (!insideQualifiedReference) {
+                               if (mustQualifyType(packageName, className)) {
+                                       if (packageName == null || packageName.length == 0)
+                                               if (unitScope != null && unitScope.fPackage.compoundName != NoCharChar)
+                                                       return; // ignore types from the default package from outside it
+                               } else {
+                                       completionName = className;
+                               }
+                       }
+                       relevance += computeRelevanceForCaseMatching(token, className);
+                       relevance += computeRelevanceForExpectingType(packageName, className);
+                       relevance += computeRelevanceForClass();
+                       relevance += computeRelevanceForException(className);
+               }
+
+               requestor.acceptClass(
+                       packageName,
+                       className,
+                       completionName,
+                       modifiers,
+                       startPosition - offset,
+                       endPosition - offset,
+                       relevance);
+       }
+       
+       /**
+        * One result of the search consists of a new interface.
+        *
+        * 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 acceptInterface(
+               char[] packageName,
+               char[] interfaceName,
+               int modifiers) {
+
+               char[] fullyQualifiedName = CharOperation.concat(packageName, interfaceName, '.');
+               char[] completionName = fullyQualifiedName;
+
+               if (this.knownTypes.containsKey(completionName)) return;
+
+               this.knownTypes.put(completionName, this);
+
+               int relevance = R_DEFAULT;
+               if (resolvingImports) {
+                       completionName = CharOperation.concat(completionName, new char[] { ';' });
+                       relevance += computeRelevanceForCaseMatching(token, fullyQualifiedName);
+               } else {
+                       if (!insideQualifiedReference) {
+                               if (mustQualifyType(packageName, interfaceName)) {
+                                       if (packageName == null || packageName.length == 0)
+                                               if (unitScope != null && unitScope.fPackage.compoundName != NoCharChar)
+                                                       return; // ignore types from the default package from outside it
+                               } else {
+                                       completionName = interfaceName;
+                               }
+                       }
+                       relevance += computeRelevanceForCaseMatching(token, interfaceName);
+                       relevance += computeRelevanceForExpectingType(packageName, interfaceName);
+                       relevance += computeRelevanceForInterface();
+               }
+               
+               requestor.acceptInterface(
+                       packageName,
+                       interfaceName,
+                       completionName,
+                       modifiers,
+                       startPosition - offset,
+                       endPosition - offset,
+                       relevance);
+       }
+
+       /**
+        * 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);
+               
+               int relevance = R_DEFAULT;
+               relevance += computeRelevanceForCaseMatching(token, packageName);
+
+               requestor.acceptPackage(
+                       packageName,
+                       resolvingImports
+                               ? CharOperation.concat(packageName, new char[] { '.', '*', ';' })
+                               : packageName,
+                       startPosition - offset,
+                       endPosition - offset,
+                       relevance);
+       }
+
+       /**
+        * 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.M".
+        *    The default package is represented by an empty array.
+        */
+       public void acceptType(char[] packageName, char[] typeName) {
+
+               char[] fullyQualifiedName = CharOperation.concat(packageName, typeName, '.');
+               char[] completionName = fullyQualifiedName;
+               
+               if (this.knownTypes.containsKey(completionName)) return;
+
+               this.knownTypes.put(completionName, this);
+
+               int relevance = R_DEFAULT;
+               if (resolvingImports) {
+                       completionName = CharOperation.concat(completionName, new char[] { ';' });
+                       relevance += computeRelevanceForCaseMatching(token, fullyQualifiedName);
+               } else {
+                       if (!insideQualifiedReference) {
+                               if (mustQualifyType(packageName, typeName)) {
+                                       if (packageName == null || packageName.length == 0)
+                                               if (unitScope != null && unitScope.fPackage.compoundName != NoCharChar)
+                                                       return; // ignore types from the default package from outside it
+                               } else {
+                                       completionName = typeName;
+                               }
+                       }
+                       relevance += computeRelevanceForCaseMatching(token, typeName);
+                       relevance += computeRelevanceForExpectingType(packageName, typeName);
+               }
+               
+               requestor.acceptType(
+                       packageName,
+                       typeName,
+                       completionName,
+                       startPosition - offset,
+                       endPosition - offset,
+                       relevance);
+       }
+
+       private void complete(AstNode astNode, Binding qualifiedBinding, Scope scope) {
+
+               setSourceRange(astNode.sourceStart, astNode.sourceEnd);
+               
+               if(parser.assistNodeParent != null) {
+                       computeExpectedTypes(parser.assistNodeParent, scope);
+               }
+
+               // defaults... some nodes will change these
+               if (astNode instanceof CompletionOnFieldType) {
+
+                       CompletionOnFieldType field = (CompletionOnFieldType) astNode;
+                       CompletionOnSingleTypeReference type = (CompletionOnSingleTypeReference) field.type;
+                       token = type.token;
+                       setSourceRange(type.sourceStart, type.sourceEnd);
+                       //              findKeywords(token, modifiers, scope); // could be the start of a field, method or member type
+                       findTypesAndPackages(token, scope);
+                       
+                       if(!field.isLocalVariable && field.modifiers == CompilerModifiers.AccDefault) {
+                               findMethods(token,null,scope.enclosingSourceType(),scope,new ObjectVector(),false,false,true,null,null,false);
+                       }
+               } else {
+                       if(astNode instanceof CompletionOnMethodReturnType) {
+                               
+                               CompletionOnMethodReturnType method = (CompletionOnMethodReturnType) astNode;
+                               SingleTypeReference type = (CompletionOnSingleTypeReference) method.returnType;
+                               token = type.token;
+                               setSourceRange(type.sourceStart, type.sourceEnd);
+                               findTypesAndPackages(token, scope);
+                               
+                               if(method.modifiers == CompilerModifiers.AccDefault) {
+                                       findMethods(token,null,scope.enclosingSourceType(),scope,new ObjectVector(),false,false,true,null,null,false);
+                               }
+                       } else {
+                               
+                               if (astNode instanceof CompletionOnSingleNameReference) {
+       
+                                       token = ((CompletionOnSingleNameReference) astNode).token;
+                                       findVariablesAndMethods(
+                                               token,
+                                               scope,
+                                               (CompletionOnSingleNameReference) astNode,
+                                               scope);
+                                       // can be the start of a qualified type name
+                                       findTypesAndPackages(token, scope);
+       
+                               } else {
+       
+                                       if (astNode instanceof CompletionOnSingleTypeReference) {
+       
+                                               token = ((CompletionOnSingleTypeReference) astNode).token;
+                                               
+                                               assistNodeIsClass = astNode instanceof CompletionOnClassReference;
+                                               assistNodeIsException = astNode instanceof CompletionOnExceptionReference;
+                                               assistNodeIsInterface = astNode instanceof CompletionOnInterfaceReference;
+       
+                                               // can be the start of a qualified type name
+                                               if (qualifiedBinding == null) {
+                                                       findTypesAndPackages(token, scope);
+                                                       } else {
+                                                               findMemberTypes(
+                                                               token,
+                                                               (ReferenceBinding) qualifiedBinding,
+                                                               scope,
+                                                               scope.enclosingSourceType());
+                                               }
+                                       } else {
+                                               
+                                               if (astNode instanceof CompletionOnQualifiedNameReference) {
+       
+                                                       insideQualifiedReference = true;
+                                                       CompletionOnQualifiedNameReference ref =
+                                                               (CompletionOnQualifiedNameReference) astNode;
+                                                       token = ref.completionIdentifier;
+                                                       long completionPosition = ref.sourcePositions[ref.sourcePositions.length - 1];
+       
+                                                       if (qualifiedBinding instanceof VariableBinding) {
+       
+                                                               setSourceRange((int) (completionPosition >>> 32), (int) completionPosition);
+                                                               TypeBinding receiverType = ((VariableBinding) qualifiedBinding).type;
+                                                               if (receiverType != null) {
+                                                                       findFieldsAndMethods(token, receiverType, scope, ref, scope,false);
+                                                               }
+       
+                                                       } else {
+       
+                                                               if (qualifiedBinding instanceof ReferenceBinding) {
+       
+                                                                       ReferenceBinding receiverType = (ReferenceBinding) qualifiedBinding;
+                                                                       setSourceRange((int) (completionPosition >>> 32), (int) completionPosition);
+       
+                                                                       findMemberTypes(token, receiverType, scope, scope.enclosingSourceType());
+       
+                                                                       findClassField(token, (TypeBinding) qualifiedBinding, scope);
+       
+                                                                       findFields(
+                                                                               token,
+                                                                               receiverType,
+                                                                               scope,
+                                                                               new ObjectVector(),
+                                                                               new ObjectVector(),
+                                                                               true,
+                                                                               ref,
+                                                                               scope,
+                                                                               false);
+       
+                                                                       findMethods(
+                                                                               token,
+                                                                               null,
+                                                                               receiverType,
+                                                                               scope,
+                                                                               new ObjectVector(),
+                                                                               true,
+                                                                               false,
+                                                                               false,
+                                                                               ref,
+                                                                               scope,
+                                                                               false);
+       
+                                                               } else {
+       
+                                                                       if (qualifiedBinding instanceof PackageBinding) {
+       
+                                                                               setSourceRange(astNode.sourceStart, (int) completionPosition);
+                                                                               // replace to the end of the completion identifier
+                                                                               findTypesAndSubpackages(token, (PackageBinding) qualifiedBinding);
+                                                                       }
+                                                               }
+                                                       }
+       
+                                               } else {
+       
+                                                               if (astNode instanceof CompletionOnQualifiedTypeReference) {
+       
+                                                               insideQualifiedReference = true;
+                                                               
+                                                               assistNodeIsClass = astNode instanceof CompletionOnQualifiedClassReference;
+                                                               assistNodeIsException = astNode instanceof CompletionOnQualifiedExceptionReference;
+                                                               assistNodeIsInterface = astNode instanceof CompletionOnQualifiedInterfaceReference;
+                                                               
+                                                               CompletionOnQualifiedTypeReference ref =
+                                                                       (CompletionOnQualifiedTypeReference) astNode;
+                                                               token = ref.completionIdentifier;
+                                                               long completionPosition = ref.sourcePositions[ref.tokens.length];
+       
+                                                               // get the source positions of the completion identifier
+                                                               if (qualifiedBinding instanceof ReferenceBinding) {
+       
+                                                                       setSourceRange((int) (completionPosition >>> 32), (int) completionPosition);
+                                                                       findMemberTypes(
+                                                                               token,
+                                                                               (ReferenceBinding) qualifiedBinding,
+                                                                               scope,
+                                                                               scope.enclosingSourceType());
+       
+                                                               } else {
+       
+                                                                       if (qualifiedBinding instanceof PackageBinding) {
+       
+                                                                               setSourceRange(astNode.sourceStart, (int) completionPosition);
+                                                                               // replace to the end of the completion identifier
+                                                                               findTypesAndSubpackages(token, (PackageBinding) qualifiedBinding);
+                                                                       }
+                                                               }
+       
+                                                       } else {
+       
+                                                               if (astNode instanceof CompletionOnMemberAccess) {
+       
+                                                                       CompletionOnMemberAccess access = (CompletionOnMemberAccess) astNode;
+                                                                       long completionPosition = access.nameSourcePosition;
+                                                                       setSourceRange((int) (completionPosition >>> 32), (int) completionPosition);
+                                       
+                                                                       token = access.token;
+       
+                                                                       findFieldsAndMethods(
+                                                                               token,
+                                                                               (TypeBinding) qualifiedBinding,
+                                                                               scope,
+                                                                               access,
+                                                                               scope,
+                                                                               false);
+       
+                                                               } else {
+       
+                                                                       if (astNode instanceof CompletionOnMessageSend) {
+       
+                                                                               CompletionOnMessageSend messageSend = (CompletionOnMessageSend) astNode;
+                                                                               TypeBinding[] argTypes =
+                                                                                       computeTypes(messageSend.arguments, (BlockScope) scope);
+                                                                               token = messageSend.selector;
+                                                                               if (qualifiedBinding == null) {
+                                                                                       
+                                                                                       findImplicitMessageSends(token, argTypes, scope, messageSend, scope);
+                                                                               } else {
+       
+                                                                                       findMethods(
+                                                                                               token,
+                                                                                               argTypes,
+                                                                                               (ReferenceBinding) qualifiedBinding,
+                                                                                               scope,
+                                                                                               new ObjectVector(),
+                                                                                               false,
+                                                                                               true,
+                                                                                               false,
+                                                                                               messageSend,
+                                                                                               scope,
+                                                                                               false);
+                                                                               }
+       
+                                                                       } else {
+       
+                                                                               if (astNode instanceof CompletionOnExplicitConstructorCall) {
+       
+                                                                                       CompletionOnExplicitConstructorCall constructorCall =
+                                                                                               (CompletionOnExplicitConstructorCall) astNode;
+                                                                                       TypeBinding[] argTypes =
+                                                                                               computeTypes(constructorCall.arguments, (BlockScope) scope);
+                                                                                       findConstructors(
+                                                                                               (ReferenceBinding) qualifiedBinding,
+                                                                                               argTypes,
+                                                                                               scope,
+                                                                                               constructorCall,
+                                                                                               false);
+       
+                                                                               } else {
+       
+                                                                                       if (astNode instanceof CompletionOnQualifiedAllocationExpression) {
+       
+                                                                                               CompletionOnQualifiedAllocationExpression allocExpression =
+                                                                                                       (CompletionOnQualifiedAllocationExpression) astNode;
+                                                                                               TypeBinding[] argTypes =
+                                                                                                       computeTypes(allocExpression.arguments, (BlockScope) scope);
+                                                                                               
+                                                                                               ReferenceBinding ref = (ReferenceBinding) qualifiedBinding;
+                                                                                               if(ref.isClass()) {
+                                                                                                       if(!ref.isAbstract()) {
+                                                                                                               findConstructors(
+                                                                                                                       ref,
+                                                                                                                       argTypes,
+                                                                                                                       scope,
+                                                                                                                       allocExpression,
+                                                                                                                       false);
+                                                                                                       }
+                                                                                               }
+                                                                                               if(!ref.isFinal()){
+                                                                                                       findAnonymousType(
+                                                                                                               ref,
+                                                                                                               argTypes,
+                                                                                                               scope,
+                                                                                                               allocExpression);
+                                                                                               }
+       
+                                                                                       } else {
+       
+                                                                                               if (astNode instanceof CompletionOnClassLiteralAccess) {
+                                                                                                       CompletionOnClassLiteralAccess access = (CompletionOnClassLiteralAccess) astNode;
+                                                                                                       setSourceRange(access.classStart, access.sourceEnd);
+                                                                       
+                                                                                                       token = access.completionIdentifier;
+                                                                       
+                                                                                                       findClassField(token, (TypeBinding) qualifiedBinding, scope);
+                                                                                               } else {
+                                                                                                       if(astNode instanceof CompletionOnMethodName) {
+                                                                                                               CompletionOnMethodName method = (CompletionOnMethodName) astNode;
+                                                                                                                       
+                                                                                                               setSourceRange(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;
+                                                                                                               }
+                                                                                                               
+                                                                                                               token = method.selector;
+                                                                                                               
+                                                                                                               findVariableNames(token, method.returnType, excludeNames);
+                                                                                                       } else {
+                                                                                                               if (astNode instanceof CompletionOnFieldName) {
+                                                                                                                       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;
+                                                                                                                       }
+                                                                                                                       
+                                                                                                                       token = field.realName;
+                                                                                                                       
+                                                                                                                       findVariableNames(field.realName, field.type, excludeNames);
+                                                                                                               } else {
+                                                                                                                       if (astNode instanceof CompletionOnLocalName ||
+                                                                                                                               astNode instanceof CompletionOnArgumentName){
+                                                                                                                               LocalDeclaration variable = (LocalDeclaration) astNode;
+                                                                                                                               
+                                                                                                                               LocalVariableBinding[] locals = ((BlockScope)scope).locals;
+                                                                                                                               char[][] excludeNames = new char[locals.length][];
+                                                                                                                               int localCount = 0;
+                                                                                                                               for(int i = 0 ; i < locals.length ; i++){
+                                                                                                                                       if(locals[i] != null) {
+                                                                                                                                               excludeNames[localCount++] = locals[i].name;
+                                                                                                                                       }
+                                                                                                                               }
+                                                                                                                               System.arraycopy(excludeNames, 0, excludeNames = new char[localCount][], 0, localCount);
+                                                                                                                               
+                                                                                                                               if(variable instanceof CompletionOnLocalName){
+                                                                                                                                       token = ((CompletionOnLocalName) variable).realName;
+                                                                                                                               } else {
+                                                                                                                                       token = ((CompletionOnArgumentName) variable).realName;
+                                                                                                                               }
+                                                                                                                               findVariableNames(token, variable.type, excludeNames);
+                                                                                                                       }
+                                                                                                               }
+                                                                                                       }
+                                                                                               }
+                                                                                       }
+                                                                               }
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+       
+//     public void complete(IType type, char[] snippet, int position, char[][] localVariableTypeNames, char[][] localVariableNames, int[] localVariableModifiers, boolean isStatic){   
+//             TypeConverter converter = new TypeConverter();
+//             
+//             IType topLevelType = type;
+//             while(topLevelType.getDeclaringType() != null) {
+//                     topLevelType = topLevelType.getDeclaringType();
+//             }
+//             
+//             CompilationResult compilationResult = new CompilationResult((topLevelType.getElementName() + ".java").toCharArray(), 1, 1, this.compilerOptions.maxProblemsPerUnit); //$NON-NLS-1$
+//     
+//             CompilationUnitDeclaration compilationUnit = new CompilationUnitDeclaration(problemReporter, compilationResult, 0);
+//     
+//             try {
+//                     TypeDeclaration typeDeclaration = converter.buildTypeDeclaration(type, compilationUnit, compilationResult, problemReporter);
+//             
+//                     if(typeDeclaration != null) {   
+//                             // build AST from snippet
+//                             Initializer fakeInitializer = parseSnippeInitializer(snippet, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic);
+//                             
+//                             // merge AST
+//                             FieldDeclaration[] oldFields = typeDeclaration.fields;
+//                             FieldDeclaration[] newFields = new FieldDeclaration[oldFields.length + 1];
+//                             System.arraycopy(oldFields, 0, newFields, 0, oldFields.length);
+//                             newFields[oldFields.length] = 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 {
+//                                             lookupEnvironment.buildTypeBindings(compilationUnit);
+//                             
+//                                             if ((unitScope = compilationUnit.scope) != null) {
+//                                                     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
+//                                                     complete(e.astNode, e.qualifiedBinding, e.scope);
+//                                             }
+//                                     }
+//                             }
+//                     }
+//             } catch(JavaModelException e) {
+//                     // Do nothing
+//             }
+//     }
+       
+//     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++) {
+//                     prefix.append(AstNode.modifiersString(localVariableModifiers[i]));
+//                     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$ 
+//             offset = prefix.length();
+//             
+//             String encoding = JavaCore.getOption(JavaCore.CORE_ENCODING);
+//             BasicCompilationUnit fakeUnit = new BasicCompilationUnit(
+//                     fakeSource, 
+//                     null,
+//                     "FakeType.java", //$NON-NLS-1$
+//                     encoding); 
+//                     
+//             actualCompletionPosition = prefix.length() + position - 1;
+//                     
+//             CompilationResult fakeResult = new CompilationResult(fakeUnit, 1, 1, this.compilerOptions.maxProblemsPerUnit);
+//             CompilationUnitDeclaration fakeAST = parser.dietParse(fakeUnit, fakeResult, actualCompletionPosition);
+//             
+//             parseMethod(fakeAST, actualCompletionPosition);
+//             
+//             return (Initializer)fakeAST.types[0].fields[0];
+//     }
+
+       /**
+        * Ask the engine to compute a completion at the specified position
+        * of the given compilation unit.
+        *
+        *  @return void
+        *      completion results are answered through a requestor.
+        *
+        *  @param sourceUnit net.sourceforge.phpdt.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 offset) {
+
+               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());
+               }
+               try {
+                       actualCompletionPosition = completionPosition - 1;
+                       this.offset = offset;
+                       // for now until we can change the UI.
+                       CompilationResult result = new CompilationResult(sourceUnit, 1, 1, this.compilerOptions.maxProblemsPerUnit);
+                       CompilationUnitDeclaration parsedUnit = parser.dietParse(sourceUnit, result, 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) {
+                                       findPackages((CompletionOnPackageReference) parsedUnit.currentPackage);
+                                       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) {
+                                                       findImports((CompletionOnImportReference) importReference);
+                                                       return;
+                                               }
+                                       }
+                               }
+
+                               if (parsedUnit.types != null) {
+                                       try {
+                                               lookupEnvironment.buildTypeBindings(parsedUnit);
+
+                                               if ((unitScope = parsedUnit.scope) != null) {
+                                                       source = sourceUnit.getContents();
+                                                       lookupEnvironment.completeTypeBindings(parsedUnit, true);
+                                                       parsedUnit.scope.faultInTypes();
+                                                       parseMethod(parsedUnit, 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(DEBUG) {
+                                                               System.out.print("COMPLETION - Completion node : "); //$NON-NLS-1$
+                                                               System.out.println(e.astNode.toString());
+                                                       }
+                                                       // if null then we found a problem in the completion node
+                                                       complete(e.astNode, e.qualifiedBinding, e.scope);
+                                               }
+                                       }
+                               }
+                       }
+
+                       /* 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) 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
+               } catch (InvalidCursorLocation e) { // may eventually report a usefull error
+               } catch (AbortCompilation e) { // ignore this exception for now since it typically means we cannot find java.lang.Object
+               } catch (CompletionNodeFound e){ // internal failure - bugs 5618
+               } finally {
+                       reset();
+               }
+       }
+
+       private TypeBinding[] computeTypes(Expression[] arguments, BlockScope scope) {
+
+               if (arguments == null)
+                       return null;
+
+               int argsLength = arguments.length;
+               TypeBinding[] argTypes = new TypeBinding[argsLength];
+               for (int a = argsLength; --a >= 0;)
+                       argTypes[a] = arguments[a].resolveType(scope);
+               return argTypes;
+       }
+       
+       private void findAnonymousType(
+               ReferenceBinding currentType,
+               TypeBinding[] argTypes,
+               Scope scope,
+               InvocationSite invocationSite) {
+
+               if (currentType.isInterface()) {
+                       char[] completion = TypeConstants.NoChar;
+                       // nothing to insert - do not want to replace the existing selector & arguments
+                       if (source == null
+                               || source.length <= endPosition
+                               || source[endPosition] != ')')
+                               completion = new char[] { ')' };
+                       
+                       requestor.acceptAnonymousType(
+                               currentType.qualifiedPackageName(),
+                               currentType.qualifiedSourceName(),
+                               TypeConstants.NoCharChar,
+                               TypeConstants.NoCharChar,
+                               TypeConstants.NoCharChar,
+                               completion,
+                               IConstants.AccPublic,
+                               endPosition - offset,
+                               endPosition - offset,
+                               R_DEFAULT);
+               } else {
+                       findConstructors(
+                               currentType,
+                               argTypes,
+                               scope,
+                               invocationSite,
+                               true);
+               }
+       }
+
+       private void findClassField(char[] token, TypeBinding receiverType, Scope scope) {
+
+               if (token == null)
+                       return;
+
+               if (token.length <= classField.length
+                       && CharOperation.prefixEquals(token, classField, false /* ignore case */
+               )) {
+                       int relevance = R_DEFAULT;
+                       relevance += computeRelevanceForCaseMatching(token, classField);
+                       relevance += computeRelevanceForExpectingType(scope.getJavaLangClass());
+                               
+                       requestor.acceptField(
+                               NoChar,
+                               NoChar,
+                               classField,
+                               NoChar,
+                               NoChar,
+                               classField,
+                               CompilerModifiers.AccStatic | CompilerModifiers.AccPublic,
+                               startPosition - offset,
+                               endPosition - offset,
+                               relevance);
+               }
+       }
+
+       private void findConstructors(
+               ReferenceBinding currentType,
+               TypeBinding[] argTypes,
+               Scope scope,
+               InvocationSite invocationSite,
+               boolean forAnonymousType) {
+
+               // 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 (options.checkVisibility
+                                               && !constructor.canBeSeenBy(invocationSite, scope)) 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 (!scope.areTypesCompatible(argTypes[a], 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 = TypeConstants.NoChar;
+                                       // nothing to insert - do not want to replace the existing selector & arguments
+                                       if (source == null
+                                               || source.length <= endPosition
+                                               || source[endPosition] != ')')
+                                               completion = new char[] { ')' };
+                                       
+                                       if(forAnonymousType){
+                                               requestor.acceptAnonymousType(
+                                                       currentType.qualifiedPackageName(),
+                                                       currentType.qualifiedSourceName(),
+                                                       parameterPackageNames,
+                                                       parameterTypeNames,
+                                                       parameterNames,
+                                                       completion,
+                                                       constructor.modifiers,
+                                                       endPosition - offset,
+                                                       endPosition - offset,
+                                                       R_DEFAULT);
+                                       } else {
+                                               requestor.acceptMethod(
+                                                       currentType.qualifiedPackageName(),
+                                                       currentType.qualifiedSourceName(),
+                                                       currentType.sourceName(),
+                                                       parameterPackageNames,
+                                                       parameterTypeNames,
+                                                       parameterNames,
+                                                       TypeConstants.NoChar,
+                                                       TypeConstants.NoChar,
+                                                       completion,
+                                                       constructor.modifiers,
+                                                       endPosition - offset,
+                                                       endPosition - offset,
+                                                       R_DEFAULT);
+                                       }
+                               }
+                       }
+               }
+       }
+       
+       // 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) {
+
+               // 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 */))        continue next;
+
+                       if (options.checkVisibility
+                               && !field.canBeSeenBy(receiverType, invocationSite, scope))     continue next;
+
+                       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.implementsInterface(otherField.declaringClass, true))
+                                                       continue next;
+                                       if (field.declaringClass.isInterface())
+                                               if (otherField.declaringClass.implementsInterface(field.declaringClass, true))
+                                                       continue next;
+                                       prefixRequired = true;
+                               }
+                       }
+
+                       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;
+                                       }
+                                       prefixRequired = true;
+                                       break;
+                               }
+                       }
+                       
+                       fieldsFound.add(new Object[]{field, receiverType});
+                       
+                       char[] completion = field.name;
+                       
+                       if(prefixRequired || options.forceImplicitQualification){
+                               char[] prefix = computePrefix(scope.enclosingSourceType(), invocationScope.enclosingSourceType(), field.isStatic());
+                               completion = CharOperation.concat(prefix,completion,'.');
+                       }
+
+                       int relevance = R_DEFAULT;
+                       relevance += computeRelevanceForCaseMatching(fieldName, field.name);
+                       relevance += computeRelevanceForExpectingType(field.type);
+
+                       requestor
+                               .acceptField(
+                                       field.declaringClass.qualifiedPackageName(),
+                                       field.declaringClass.qualifiedSourceName(),
+                                       field.name,
+                                       field.type.qualifiedPackageName(),
+                                       field.type.qualifiedSourceName(),
+                                       completion,
+                       // may include some qualification to resolve ambiguities
+                       field.modifiers, startPosition - offset, endPosition - offset,
+                       relevance);
+               }
+       }
+
+       private void findFields(
+               char[] fieldName,
+               ReferenceBinding receiverType,
+               Scope scope,
+               ObjectVector fieldsFound,
+               ObjectVector localsFound,
+               boolean onlyStaticFields,
+               InvocationSite invocationSite,
+               Scope invocationScope,
+               boolean implicitCall) {
+
+               if (fieldName == null)
+                       return;
+
+               ReferenceBinding currentType = receiverType;
+               ReferenceBinding[][] interfacesToVisit = null;
+               int lastPosition = -1;
+               do {
+
+                       ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
+                       if (itsInterfaces != NoSuperInterfaces) {
+
+                               if (interfacesToVisit == null)
+                                       interfacesToVisit = new ReferenceBinding[5][];
+
+                               if (++lastPosition == interfacesToVisit.length)
+                                       System.arraycopy(
+                                               interfacesToVisit,
+                                               0,
+                                               interfacesToVisit = new ReferenceBinding[lastPosition * 2][],
+                                               0,
+                                               lastPosition);
+                               interfacesToVisit[lastPosition] = itsInterfaces;
+                       }
+
+                       FieldBinding[] fields = currentType.availableFields();
+                       if(fields != null) {
+                               findFields(
+                                       fieldName,
+                                       fields,
+                                       scope,
+                                       fieldsFound,
+                                       localsFound,
+                                       onlyStaticFields,
+                                       receiverType,
+                                       invocationSite,
+                                       invocationScope,
+                                       implicitCall);
+                       }
+                       currentType = currentType.superclass();
+               } while (currentType != null);
+
+               if (interfacesToVisit != null) {
+                       for (int i = 0; i <= lastPosition; i++) {
+                               ReferenceBinding[] interfaces = interfacesToVisit[i];
+                               for (int j = 0, length = interfaces.length; j < length; j++) {
+
+                                       ReferenceBinding anInterface = interfaces[j];
+                                       if ((anInterface.tagBits & TagBits.InterfaceVisited) == 0) {
+                                               // if interface as not already been visited
+                                               anInterface.tagBits |= TagBits.InterfaceVisited;
+
+                                               FieldBinding[] fields = anInterface.availableFields();
+                                               if(fields !=  null) {
+                                                       findFields(
+                                                               fieldName,
+                                                               fields,
+                                                               scope,
+                                                               fieldsFound,
+                                                               localsFound,
+                                                               onlyStaticFields,
+                                                               receiverType,
+                                                               invocationSite,
+                                                               invocationScope,
+                                                               implicitCall);
+                                               }
+
+                                               ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
+                                               if (itsInterfaces != NoSuperInterfaces) {
+                                                       if (++lastPosition == interfacesToVisit.length)
+                                                               System.arraycopy(
+                                                                       interfacesToVisit,
+                                                                       0,
+                                                                       interfacesToVisit = new ReferenceBinding[lastPosition * 2][],
+                                                                       0,
+                                                                       lastPosition);
+                                                       interfacesToVisit[lastPosition] = itsInterfaces;
+                                               }
+                                       }
+                               }
+                       }
+
+                       // bit reinitialization
+                       for (int i = 0; i <= lastPosition; i++) {
+                               ReferenceBinding[] interfaces = interfacesToVisit[i];
+                               for (int j = 0, length = interfaces.length; j < length; j++)
+                                       interfaces[j].tagBits &= ~TagBits.InterfaceVisited;
+                       }
+               }
+       }
+
+       private void findFieldsAndMethods(
+               char[] token,
+               TypeBinding receiverType,
+               Scope scope,
+               InvocationSite invocationSite,
+               Scope invocationScope,
+               boolean implicitCall) {
+
+               if (token == null)
+                       return;
+
+               if (receiverType.isBaseType())
+                       return; // nothing else is possible with base types
+
+               if (receiverType.isArrayType()) {
+                       if (token.length <= lengthField.length
+                               && CharOperation.prefixEquals(token, lengthField, false /* ignore case */
+                       )) {
+                               
+                               int relevance = R_DEFAULT;
+                               relevance += computeRelevanceForCaseMatching(token,lengthField);
+                               relevance += computeRelevanceForExpectingType(BaseTypes.IntBinding);
+                               
+                               requestor.acceptField(
+                                       NoChar,
+                                       NoChar,
+                                       lengthField,
+                                       NoChar,
+                                       NoChar,
+                                       lengthField,
+                                       CompilerModifiers.AccPublic,
+                                       startPosition - offset,
+                                       endPosition - offset,
+                                       relevance);
+                       }
+                       receiverType = scope.getJavaLangObject();
+               }
+
+               findFields(
+                       token,
+                       (ReferenceBinding) receiverType,
+                       scope,
+                       new ObjectVector(),
+                       new ObjectVector(),
+                       false,
+                       invocationSite,
+                       invocationScope,
+                       implicitCall);
+
+               findMethods(
+                       token,
+                       null,
+                       (ReferenceBinding) receiverType,
+                       scope,
+                       new ObjectVector(),
+                       false,
+                       false,
+                       false,
+                       invocationSite,
+                       invocationScope,
+                       implicitCall);
+       }
+
+       private void findImports(CompletionOnImportReference importReference) {
+               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[]{'.'});
+
+               resolvingImports = true;
+               setSourceRange(
+                       importReference.sourceStart,
+                       importReference.declarationSourceEnd);
+                       
+               token =  importName;
+               // want to replace the existing .*;
+               nameEnvironment.findPackages(importName, this);
+               nameEnvironment.findTypes(importName, this);
+       }
+
+       // what about onDemand types? Ignore them since it does not happen!
+       // import p1.p2.A.*;
+       private void findKeywords(char[] keyword, char[][] choices, Scope scope) {
+
+               int length = keyword.length;
+               if (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 = R_DEFAULT;
+                                       relevance += computeRelevanceForCaseMatching(keyword, choices[i]);
+                                       
+                                       requestor.acceptKeyword(choices[i], startPosition - offset, endPosition - offset,relevance);
+                               }
+       }
+
+       // Helper method for findMemberTypes(char[], ReferenceBinding, Scope)
+       private void findMemberTypes(
+               char[] typeName,
+               ReferenceBinding[] memberTypes,
+               ObjectVector typesFound,
+               ReferenceBinding receiverType,
+               SourceTypeBinding invocationType) {
+
+               // 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 (typeLength > memberType.sourceName.length)
+                               continue next;
+
+                       if (!CharOperation.prefixEquals(typeName, memberType.sourceName, false
+                               /* ignore case */
+                               ))
+                               continue next;
+
+                       if (options.checkVisibility
+                               && !memberType.canBeSeenBy(receiverType, invocationType))
+                               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);
+
+                       int relevance = R_DEFAULT;
+                       relevance += computeRelevanceForCaseMatching(typeName, memberType.sourceName);
+                       relevance += computeRelevanceForExpectingType(memberType);
+
+                       if (memberType.isClass()) {
+                               relevance += computeRelevanceForClass();
+                               requestor.acceptClass(
+                                       memberType.qualifiedPackageName(),
+                                       memberType.qualifiedSourceName(),
+                                       memberType.sourceName(),
+                                       memberType.modifiers,
+                                       startPosition - offset,
+                                       endPosition - offset,
+                                       relevance);
+
+                       } else {
+                               relevance += computeRelevanceForInterface();
+                               requestor.acceptInterface(
+                                       memberType.qualifiedPackageName(),
+                                       memberType.qualifiedSourceName(),
+                                       memberType.sourceName(),
+                                       memberType.modifiers,
+                                       startPosition - offset,
+                                       endPosition - offset,
+                                       relevance);
+                       }
+               }
+       }
+
+       private void findMemberTypes(
+               char[] typeName,
+               ReferenceBinding receiverType,
+               Scope scope,
+               SourceTypeBinding typeInvocation) {
+
+               ReferenceBinding currentType = receiverType;
+               if (typeName == null)
+                       return;
+
+               if (currentType.superInterfaces() == null)
+                       return; // we're trying to find a supertype
+
+               ObjectVector typesFound = new ObjectVector();
+               if (insideQualifiedReference
+                       || typeName.length == 0) { // do not search up the hierarchy
+
+                       findMemberTypes(
+                               typeName,
+                               currentType.memberTypes(),
+                               typesFound,
+                               receiverType,
+                               typeInvocation);
+                       return;
+               }
+
+               ReferenceBinding[][] interfacesToVisit = null;
+               int lastPosition = -1;
+
+               do {
+
+                       ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
+                       if (itsInterfaces != NoSuperInterfaces) {
+
+                               if (interfacesToVisit == null)
+                                       interfacesToVisit = new ReferenceBinding[5][];
+
+                               if (++lastPosition == interfacesToVisit.length)
+                                       System.arraycopy(
+                                               interfacesToVisit,
+                                               0,
+                                               interfacesToVisit = new ReferenceBinding[lastPosition * 2][],
+                                               0,
+                                               lastPosition);
+                               interfacesToVisit[lastPosition] = itsInterfaces;
+                       }
+
+                       findMemberTypes(
+                               typeName,
+                               currentType.memberTypes(),
+                               typesFound,
+                               receiverType,
+                               typeInvocation);
+                       currentType = currentType.superclass();
+
+               } while (currentType != null);
+
+               if (interfacesToVisit != null) {
+                       for (int i = 0; i <= lastPosition; i++) {
+                               ReferenceBinding[] interfaces = interfacesToVisit[i];
+                               for (int j = 0, length = interfaces.length; j < length; j++) {
+
+                                       ReferenceBinding anInterface = interfaces[j];
+                                       if ((anInterface.tagBits & TagBits.InterfaceVisited) == 0) {
+                                               // if interface as not already been visited
+                                               anInterface.tagBits |= TagBits.InterfaceVisited;
+
+                                               findMemberTypes(
+                                                       typeName,
+                                                       anInterface.memberTypes(),
+                                                       typesFound,
+                                                       receiverType,
+                                                       typeInvocation);
+
+                                               ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
+                                               if (itsInterfaces != NoSuperInterfaces) {
+
+                                                       if (++lastPosition == interfacesToVisit.length)
+                                                               System.arraycopy(
+                                                                       interfacesToVisit,
+                                                                       0,
+                                                                       interfacesToVisit = new ReferenceBinding[lastPosition * 2][],
+                                                                       0,
+                                                                       lastPosition);
+                                                       interfacesToVisit[lastPosition] = itsInterfaces;
+                                               }
+                                       }
+                               }
+                       }
+
+                       // bit reinitialization
+                       for (int i = 0; i <= lastPosition; i++) {
+                               ReferenceBinding[] interfaces = interfacesToVisit[i];
+                               for (int j = 0, length = interfaces.length; j < length; j++)
+                                       interfaces[j].tagBits &= ~TagBits.InterfaceVisited;
+                       }
+               }
+       }
+
+       private void findIntefacesMethods(
+               char[] selector,
+               TypeBinding[] argTypes,
+               ReferenceBinding receiverType,
+               ReferenceBinding[] itsInterfaces,
+               Scope scope,
+               ObjectVector methodsFound,
+               boolean onlyStaticMethods,
+               boolean exactMatch,
+               boolean isCompletingDeclaration,
+               InvocationSite invocationSite,
+               Scope invocationScope,
+               boolean implicitCall) {
+
+               if (selector == null)
+                       return;
+
+               if (itsInterfaces != NoSuperInterfaces) {
+                       ReferenceBinding[][] interfacesToVisit = new ReferenceBinding[5][];
+                       int lastPosition = 0;
+                       interfacesToVisit[lastPosition] = itsInterfaces;
+                       
+                       for (int i = 0; i <= lastPosition; i++) {
+                               ReferenceBinding[] interfaces = interfacesToVisit[i];
+
+                               for (int j = 0, length = interfaces.length; j < length; j++) {
+                                       ReferenceBinding currentType = interfaces[j];
+
+                                       if ((currentType.tagBits & TagBits.InterfaceVisited) == 0) {
+                                               // if interface as not already been visited
+                                               currentType.tagBits |= TagBits.InterfaceVisited;
+
+                                               MethodBinding[] methods = currentType.availableMethods();
+                                               if(methods != null) {
+                                                       if(isCompletingDeclaration){
+       
+                                                               findLocalMethodDeclarations(
+                                                                       selector,
+                                                                       methods,
+                                                                       scope,
+                                                                       methodsFound,
+                                                                       onlyStaticMethods,
+                                                                       exactMatch,
+                                                                       receiverType);
+       
+                                                       } else {
+       
+                                                               findLocalMethods(
+                                                                       selector,
+                                                                       argTypes,
+                                                                       methods,
+                                                                       scope,
+                                                                       methodsFound,
+                                                                       onlyStaticMethods,
+                                                                       exactMatch,
+                                                                       receiverType,
+                                                                       invocationSite,
+                                                                       invocationScope,
+                                                                       implicitCall);
+                                                       }
+                                               }
+
+                                               itsInterfaces = currentType.superInterfaces();
+                                               if (itsInterfaces != NoSuperInterfaces) {
+
+                                                       if (++lastPosition == interfacesToVisit.length)
+                                                               System.arraycopy(
+                                                                       interfacesToVisit,
+                                                                       0,
+                                                                       interfacesToVisit = new ReferenceBinding[lastPosition * 2][],
+                                                                       0,
+                                                                       lastPosition);
+                                                       interfacesToVisit[lastPosition] = itsInterfaces;
+                                               }
+                                       }
+                               }
+                       }
+
+                       // bit reinitialization
+                       for (int i = 0; i <= lastPosition; i++) {
+                               ReferenceBinding[] interfaces = interfacesToVisit[i];
+
+                               for (int j = 0, length = interfaces.length; j < length; j++){
+                                       interfaces[j].tagBits &= ~TagBits.InterfaceVisited;
+                               }
+                       }
+               }
+       }
+       
+       private void findImplicitMessageSends(
+               char[] token,
+               TypeBinding[] argTypes,
+               Scope scope,
+               InvocationSite invocationSite,
+               Scope invocationScope) {
+
+               if (token == null)
+                       return;
+
+               boolean staticsOnly = false;
+               // need to know if we're in a static context (or inside a constructor)
+               ObjectVector methodsFound = new ObjectVector();
+
+               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,
+                                               argTypes,
+                                               enclosingType,
+                                               classScope,
+                                               methodsFound,
+                                               staticsOnly,
+                                               true,
+                                               false,
+                                               invocationSite,
+                                               invocationScope,
+                                               true);
+                                       staticsOnly |= enclosingType.isStatic();
+                                       break;
+
+                               case Scope.COMPILATION_UNIT_SCOPE :
+                                       break done;
+                       }
+                       scope = scope.parent;
+               }
+       }
+
+       // Helper method for findMethods(char[], TypeBinding[], ReferenceBinding, Scope, ObjectVector, boolean, boolean, boolean)
+       private void findLocalMethods(
+               char[] methodName,
+               TypeBinding[] argTypes,
+               MethodBinding[] methods,
+               Scope scope,
+               ObjectVector methodsFound,
+               boolean onlyStaticMethods,
+               boolean exactMatch,
+               ReferenceBinding receiverType,
+               InvocationSite invocationSite,
+               Scope invocationScope,
+               boolean implicitCall) {
+
+               // 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 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 (noVoidReturnType && method.returnType == BaseTypes.VoidBinding) continue next;
+                       if (onlyStaticMethods && !method.isStatic()) continue next;
+
+                       if (options.checkVisibility
+                               && !method.canBeSeenBy(receiverType, invocationSite, 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 */
+                                       ))
+                                       continue next;
+                       }
+                       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 (!scope.areTypesCompatible(argTypes[a], 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)
+                                       && method.areParametersEqual(otherMethod)) {
+
+                                       if (method.declaringClass.isSuperclassOf(otherMethod.declaringClass))
+                                               continue next;
+
+                                       if (otherMethod.declaringClass.isInterface())
+                                               if (method
+                                                       .declaringClass
+                                                       .implementsInterface(otherMethod.declaringClass, true))
+                                                       continue next;
+
+                                       if (method.declaringClass.isInterface())
+                                               if(otherMethod
+                                                       .declaringClass
+                                                       .implementsInterface(method.declaringClass,true))
+                                                       continue next;
+                                       prefixRequired = true;
+                               }
+                       }
+
+                       methodsFound.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.parameters[i];
+                               parameterPackageNames[i] = type.qualifiedPackageName();
+                               parameterTypeNames[i] = type.qualifiedSourceName();
+                       }
+                       char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
+
+                       char[] completion = TypeConstants.NoChar;
+                       
+                       int previousStartPosition = startPosition;
+                       
+                       // nothing to insert - do not want to replace the existing selector & arguments
+                       if (!exactMatch) {
+                               if (source != null
+                                       && source.length > endPosition
+                                       && source[endPosition] == '(')
+                                       completion = method.selector;
+                               else
+                                       completion = CharOperation.concat(method.selector, new char[] { '(', ')' });
+                       } else {
+                               if(prefixRequired && (source != null)) {
+                                       completion = CharOperation.subarray(source, startPosition, endPosition);
+                               } else {
+                                       startPosition = endPosition;
+                               }
+                       }
+                       
+                       if(prefixRequired || options.forceImplicitQualification){
+                               char[] prefix = computePrefix(scope.enclosingSourceType(), invocationScope.enclosingSourceType(), method.isStatic());
+                               completion = CharOperation.concat(prefix,completion,'.');
+                       }
+
+                       int relevance = R_DEFAULT;
+                       relevance += computeRelevanceForCaseMatching(methodName, method.selector);
+                       relevance += computeRelevanceForExpectingType(method.returnType);
+
+                       requestor.acceptMethod(
+                               method.declaringClass.qualifiedPackageName(),
+                               method.declaringClass.qualifiedSourceName(),
+                               method.selector,
+                               parameterPackageNames,
+                               parameterTypeNames,
+                               parameterNames,
+                               method.returnType.qualifiedPackageName(),
+                               method.returnType.qualifiedSourceName(),
+                               completion,
+                               method.modifiers,
+                               startPosition - offset,
+                               endPosition - offset,
+                               relevance);
+                       startPosition = previousStartPosition;
+               }
+       }
+       
+       private int computeRelevanceForCaseMatching(char[] token, char[] proposalName){
+               if (CharOperation.prefixEquals(token, proposalName, true /* do not ignore case */)) {
+                       return  R_CASE;
+               } else {
+                       return R_DEFAULT;
+               }
+       }
+       private int computeRelevanceForClass(){
+               if(assistNodeIsClass) {
+                       return R_CLASS;
+               }
+               return 0;
+       }
+       private int computeRelevanceForInterface(){
+               if(assistNodeIsInterface) {
+                       return R_INTERFACE;
+               }
+               return R_DEFAULT;
+       }
+       private int computeRelevanceForException(char[] proposalName){
+               
+               if(assistNodeIsException &&
+                       (CharOperation.match(EXCEPTION_PATTERN, proposalName, false) ||
+                       CharOperation.match(ERROR_PATTERN, proposalName, false))) { 
+                       return R_EXCEPTION;
+               }
+               return R_DEFAULT;
+       }
+       private int computeRelevanceForExpectingType(TypeBinding proposalType){
+               if(expectedTypes != null && proposalType != null) {
+                       for (int i = 0; i < expectedTypes.length; i++) {
+                               if(Scope.areTypesCompatible(proposalType, expectedTypes[i])) {
+                                       return R_EXPECTED_TYPE;
+                               }
+                       }
+               } 
+               return R_DEFAULT;
+       }
+       private int computeRelevanceForExpectingType(char[] packageName, char[] typeName){
+               if(expectedTypes != null) {
+                       for (int i = 0; i < expectedTypes.length; i++) {
+                               if(CharOperation.equals(expectedTypes[i].qualifiedPackageName(), packageName) &&
+                                       CharOperation.equals(expectedTypes[i].qualifiedSourceName(), typeName)) {
+                                       return R_EXPECTED_TYPE;
+                               }
+                       }
+               } 
+               return R_DEFAULT;
+       }
+
+       // 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 onlyStaticMethods,
+               boolean exactMatch,
+               ReferenceBinding receiverType) {
+
+               // 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()) continue next;
+
+                       //              if (noVoidReturnType && method.returnType == BaseTypes.VoidBinding) continue next;
+                       if (onlyStaticMethods && !method.isStatic()) continue next;
+
+                       if (options.checkVisibility
+                               && !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 */
+                                       ))
+                                       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)
+                                       && method.areParametersEqual(otherMethod)) {
+                                       continue next;
+                               }
+                       }
+
+                       methodsFound.add(method);
+                       
+                       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.parameters[i];
+                               parameterPackageNames[i] = type.qualifiedPackageName();
+                               parameterTypeNames[i] = type.qualifiedSourceName();
+                       }
+
+                       char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
+                       
+                       StringBuffer completion = new StringBuffer(10);
+                       // flush uninteresting modifiers
+                       int insertedModifiers = method.modifiers & ~(CompilerModifiers.AccNative | CompilerModifiers.AccAbstract);
+
+                       if (!exactMatch) {
+                               if(insertedModifiers != CompilerModifiers.AccDefault){
+                                       completion.append(AstNode.modifiersString(insertedModifiers));
+                               }
+                               char[] returnPackageName = method.returnType.qualifiedPackageName();
+                               char[] returnTypeName = method.returnType.qualifiedSourceName();
+                               if(mustQualifyType(returnPackageName, returnTypeName)) {
+                                       completion.append(CharOperation.concat(returnPackageName, returnTypeName,'.'));
+                               } else {
+                                       completion.append(method.returnType.sourceName());
+                               }
+                               completion.append(' ');
+                               completion.append(method.selector);
+                               completion.append('(');
+
+                               for(int i = 0; i < length ; i++){
+                                       if(mustQualifyType(parameterPackageNames[i], parameterTypeNames[i])){
+                                               completion.append(CharOperation.concat(parameterPackageNames[i], parameterTypeNames[i], '.'));
+                                       } else {
+                                               completion.append(parameterTypeNames[i]);
+                                       }
+                                       completion.append(' ');
+                                       if(parameterNames != null){
+                                               completion.append(parameterNames[i]);
+                                       } else {
+                                               completion.append('%');
+                                       }
+                                       if(i != (length - 1))
+                                               completion.append(','); 
+                               }
+                               completion.append(')');
+                               
+                               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++){
+                                               ReferenceBinding exception = exceptions[i];
+
+                                               char[] exceptionPackageName = exception.qualifiedPackageName();
+                                               char[] exceptionTypeName = exception.qualifiedSourceName();
+                                               
+                                               if(i != 0){
+                                                       completion.append(',');
+                                                       completion.append(' ');
+                                               }
+                                               
+                                               if(mustQualifyType(exceptionPackageName, exceptionTypeName)){
+                                                       completion.append(CharOperation.concat(exceptionPackageName, exceptionTypeName, '.'));
+                                               } else {
+                                                       completion.append(exception.sourceName());
+                                               }
+                                       }
+                               }
+                       }
+
+                       int relevance = R_DEFAULT;
+                       relevance += computeRelevanceForCaseMatching(methodName, method.selector);
+
+                       requestor.acceptMethodDeclaration(
+                               method.declaringClass.qualifiedPackageName(),
+                               method.declaringClass.qualifiedSourceName(),
+                               method.selector,
+                               parameterPackageNames,
+                               parameterTypeNames,
+                               parameterNames,
+                               method.returnType.qualifiedPackageName(),
+                               method.returnType.qualifiedSourceName(),
+                               completion.toString().toCharArray(),
+                               method.modifiers,
+                               startPosition - offset,
+                               endPosition - offset,
+                               relevance);
+               }
+       }
+       private void findMethods(
+               char[] selector,
+               TypeBinding[] argTypes,
+               ReferenceBinding receiverType,
+               Scope scope,
+               ObjectVector methodsFound,
+               boolean onlyStaticMethods,
+               boolean exactMatch,
+               boolean isCompletingDeclaration,
+               InvocationSite invocationSite,
+               Scope invocationScope,
+               boolean implicitCall) {
+               if (selector == null)
+                       return;
+               
+               if(isCompletingDeclaration) {
+                       MethodBinding[] methods = receiverType.availableMethods();
+                       if (methods != null){
+                               for (int i = 0; i < methods.length; i++) {
+                                       if(!methods[i].isDefaultAbstract()) {
+                                               methodsFound.add(methods[i]);
+                                       }
+                               }
+                       }
+               }
+               
+               ReferenceBinding currentType = receiverType;
+               if (receiverType.isInterface()) {
+                       if(isCompletingDeclaration) {
+                               findIntefacesMethods(
+                                       selector,
+                                       argTypes,
+                                       receiverType,
+                                       currentType.superInterfaces(),
+                                       scope,
+                                       methodsFound,
+                                       onlyStaticMethods,
+                                       exactMatch,
+                                       isCompletingDeclaration,
+                                       invocationSite,
+                                       invocationScope,
+                                       implicitCall);
+                       } else {
+                               findIntefacesMethods(
+                                       selector,
+                                       argTypes,
+                                       receiverType,
+                                       new ReferenceBinding[]{currentType},
+                                       scope,
+                                       methodsFound,
+                                       onlyStaticMethods,
+                                       exactMatch,
+                                       isCompletingDeclaration,
+                                       invocationSite,
+                                       invocationScope,
+                                       implicitCall);
+                       }
+                       
+                       currentType = scope.getJavaLangObject();
+               } else {
+                       if(isCompletingDeclaration){
+                               findIntefacesMethods(
+                                       selector,
+                                       argTypes,
+                                       receiverType,
+                                       currentType.superInterfaces(),
+                                       scope,
+                                       methodsFound,
+                                       onlyStaticMethods,
+                                       exactMatch,
+                                       isCompletingDeclaration,
+                                       invocationSite,
+                                       invocationScope,
+                                       implicitCall);
+                               
+                               currentType = receiverType.superclass();
+                       }
+               }
+               boolean hasPotentialDefaultAbstractMethods = true;
+               while (currentType != null) {
+                       
+                       MethodBinding[] methods = currentType.availableMethods();
+                       if(methods != null) {
+                               if(isCompletingDeclaration){
+                                       findLocalMethodDeclarations(
+                                               selector,
+                                               methods,
+                                               scope,
+                                               methodsFound,
+                                               onlyStaticMethods,
+                                               exactMatch,
+                                               receiverType);
+                               } else{
+                                       findLocalMethods(
+                                               selector,
+                                               argTypes,
+                                               methods,
+                                               scope,
+                                               methodsFound,
+                                               onlyStaticMethods,
+                                               exactMatch,
+                                               receiverType,
+                                               invocationSite,
+                                               invocationScope,
+                                               implicitCall);
+                               }
+                       }
+                       
+                       if(hasPotentialDefaultAbstractMethods && currentType.isAbstract()){
+                               findIntefacesMethods(
+                                       selector,
+                                       argTypes,
+                                       receiverType,
+                                       currentType.superInterfaces(),
+                                       scope,
+                                       methodsFound,
+                                       onlyStaticMethods,
+                                       exactMatch,
+                                       isCompletingDeclaration,
+                                       invocationSite,
+                                       invocationScope,
+                                       implicitCall);
+                       } else {
+                               hasPotentialDefaultAbstractMethods = false;
+                       }
+                       currentType = currentType.superclass();
+               }
+       }
+       private char[][] findMethodParameterNames(MethodBinding method, char[][] parameterTypeNames){
+               ReferenceBinding bindingType = method.declaringClass;
+
+               char[][] parameterNames = null;
+               
+               int length = parameterTypeNames.length;
+
+               if (length == 0){
+                       return TypeConstants.NoCharChar;
+               }
+               // look into the corresponding unit if it is available
+               if (bindingType instanceof SourceTypeBinding){
+                       SourceTypeBinding sourceType = (SourceTypeBinding) bindingType;
+
+                       if (sourceType.scope != null){
+                               TypeDeclaration parsedType;
+
+                               if ((parsedType = sourceType.scope.referenceContext) != null){
+                                       AbstractMethodDeclaration methodDecl = parsedType.declarationOf(method);
+
+                                       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){
+                       NameEnvironmentAnswer answer = nameEnvironment.findType(bindingType.compoundName);
+
+                       if(answer != null){
+                               if(answer.isSourceType()) {
+                                       ISourceType sourceType = answer.getSourceTypes()[0];
+                                       ISourceMethod[] sourceMethods = sourceType.getMethods();
+                                       int len = sourceMethods == null ? 0 : sourceMethods.length;
+                                       for(int i = 0; i < len ; i++){
+                                               ISourceMethod sourceMethod = sourceMethods[i];
+                                               char[][] argTypeNames = sourceMethod.getArgumentTypeNames();
+
+                                               if(argTypeNames != null &&
+                                                       CharOperation.equals(method.selector,sourceMethod.getSelector()) &&
+                                                       CharOperation.equals(argTypeNames,parameterTypeNames)){
+                                                       parameterNames = sourceMethod.getArgumentNames();
+                                                       break;
+                                               }
+                                       }
+                               } 
+                       }
+               }
+               return parameterNames;
+       }
+       
+       private void findNestedTypes(
+               char[] typeName,
+               SourceTypeBinding currentType,
+               Scope scope) {
+               if (typeName == null)
+                       return;
+
+               int typeLength = typeName.length;
+
+               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.scopeIndex; i < length; i++) {
+
+                                               if (blockScope.subscopes[i] instanceof ClassScope) {
+                                                       SourceTypeBinding localType =
+                                                               ((ClassScope) blockScope.subscopes[i]).referenceContext.binding;
+
+                                                       if (!localType.isAnonymousType()) {
+                                                               if (typeLength > localType.sourceName.length)
+                                                                       continue next;
+                                                               if (!CharOperation.prefixEquals(typeName, localType.sourceName, false
+                                                                       /* ignore case */
+                                                                       ))
+                                                                       continue next;
+
+                                                               int relevance = R_DEFAULT;
+                                                               relevance += computeRelevanceForCaseMatching(typeName, localType.sourceName);
+                                                               relevance += computeRelevanceForExpectingType(localType);
+                                                               relevance += computeRelevanceForClass();
+                                                               
+                                                               requestor.acceptClass(
+                                                                       localType.qualifiedPackageName(),
+                                                                       localType.sourceName,
+                                                                       localType.sourceName,
+                                                                       localType.modifiers,
+                                                                       startPosition - offset,
+                                                                       endPosition - offset,
+                                                                       relevance);
+                                                       }
+                                               }
+                                       }
+                                       break;
+
+                               case Scope.CLASS_SCOPE :
+                                       findMemberTypes(typeName, scope.enclosingSourceType(), scope, currentType);
+                                       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) {
+
+               token = CharOperation.concatWith(packageStatement.tokens, '.');
+               if (token.length == 0)
+                       return;
+
+               setSourceRange(packageStatement.sourceStart, packageStatement.sourceEnd);
+               nameEnvironment.findPackages(CharOperation.toLowerCase(token), this);
+       }
+
+       private void findTypesAndPackages(char[] token, Scope scope) {
+
+               if (token == null)
+                       return;
+
+               if (scope.enclosingSourceType() != null)
+                       findNestedTypes(token, scope.enclosingSourceType(), scope);
+
+               if (unitScope != null) {
+                       int typeLength = token.length;
+                       SourceTypeBinding[] types = unitScope.topLevelTypes;
+
+                       for (int i = 0, length = types.length; i < length; i++) {
+                               SourceTypeBinding sourceType = types[i]; 
+
+                               if (typeLength > sourceType.sourceName.length)  continue;
+                               
+                               if (!CharOperation.prefixEquals(token, sourceType.sourceName, false))   continue;
+
+                               int relevance = R_DEFAULT;
+                               relevance += computeRelevanceForCaseMatching(token, sourceType.sourceName);
+                               relevance += computeRelevanceForExpectingType(sourceType);
+
+                               if (sourceType.isClass()){
+                                       relevance += computeRelevanceForClass();
+                                       requestor.acceptClass(
+                                               sourceType.qualifiedPackageName(),
+                                               sourceType.sourceName(),
+                                               sourceType.sourceName(),
+                                               sourceType.modifiers,
+                                               startPosition - offset, 
+                                               endPosition - offset,
+                                               relevance);
+                               } else {
+                                       relevance += computeRelevanceForInterface();
+                                       requestor.acceptInterface(
+                                               sourceType.qualifiedPackageName(),
+                                               sourceType.sourceName(),
+                                               sourceType.sourceName(),
+                                               sourceType.modifiers,
+                                               startPosition - offset,
+                                               endPosition - offset,
+                                               relevance);
+                               }
+                       }
+               }
+
+               if (token.length == 0)
+                       return;
+
+               findKeywords(token, baseTypes, scope);
+               nameEnvironment.findTypes(token, this);
+               nameEnvironment.findPackages(token, this);
+       }
+
+       private void findTypesAndSubpackages(
+               char[] token,
+               PackageBinding packageBinding) {
+
+               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] = '.';
+               }
+               nameEnvironment.findTypes(qualifiedName, this);
+               nameEnvironment.findPackages(qualifiedName, this);
+       }
+
+       private void findVariablesAndMethods(
+               char[] token,
+               Scope scope,
+               InvocationSite invocationSite,
+               Scope invocationScope) {
+
+               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;
+
+               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;
+
+                               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 */
+                                                       ))
+                                                       continue next;
+
+                                               if (local.isSecret())
+                                                       continue next;
+
+                                               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 = R_DEFAULT;
+                                               relevance += computeRelevanceForCaseMatching(token, local.name);
+                                               relevance += computeRelevanceForExpectingType(local.type);
+                                               
+                                               requestor.acceptLocalVariable(
+                                                       local.name,
+                                                       local.type == null 
+                                                               ? NoChar
+                                                               : local.type.qualifiedPackageName(),
+                                                       local.type == null
+                                                               ? local.declaration.type.toString().toCharArray()
+                                                               : local.type.qualifiedSourceName(),
+                                                       local.modifiers,
+                                                       startPosition - offset,
+                                                       endPosition - offset,
+                                                       relevance);
+                                       }
+                                       break;
+
+                               case Scope.COMPILATION_UNIT_SCOPE :
+                                       break done1;
+                       }
+                       currentScope = currentScope.parent;
+               }
+
+               currentScope = scope;
+
+               done2 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
+
+                       switch (currentScope.kind) {
+
+                               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 { */
+                                       findFields(
+                                               token,
+                                               enclosingType,
+                                               classScope,
+                                               fieldsFound,
+                                               localsFound,
+                                               staticsOnly,
+                                               invocationSite,
+                                               invocationScope,
+                                               true);
+
+                                       findMethods(
+                                               token,
+                                               null,
+                                               enclosingType,
+                                               classScope,
+                                               methodsFound,
+                                               staticsOnly,
+                                               false,
+                                               false,
+                                               invocationSite,
+                                               invocationScope,
+                                               true);
+                                       staticsOnly |= enclosingType.isStatic();
+                                       //                              }
+                                       break;
+
+                               case Scope.COMPILATION_UNIT_SCOPE :
+                                       break done2;
+                       }
+                       currentScope = currentScope.parent;
+               }
+       }
+
+       // Helper method for private void findVariableNames(char[] name, TypeReference type )
+       private void findVariableName(char[] token, char[] qualifiedPackageName, char[] qualifiedSourceName, char[] sourceName, char[][] excludeNames, int dim){
+                       if(sourceName == null || sourceName.length == 0)
+                               return;
+                               
+                       char[] name = null;
+                       
+                       // compute variable name for base type
+                       try{
+                               nameScanner.setSource(sourceName);
+        nameScanner.getNextToken();  //        switch (nameScanner.getNextToken()) {
+//                                     case TokenNameint :
+//                                     case TokenNamebyte :
+//                                     case TokenNameshort :
+//                                     case TokenNamechar :
+//                                     case TokenNamelong :
+//                                     case TokenNamefloat :
+//                                     case TokenNamedouble :
+//                                     case TokenNameboolean :
+//                                             if(token != null && token.length != 0)
+//                                                     return;
+//                                             name = computeBaseNames(sourceName[0], excludeNames);
+//                                             break;
+//                             }
+                               if(name != null) {
+                                       int relevance = R_DEFAULT;
+                                       relevance += computeRelevanceForCaseMatching(token, name);
+                                       
+                                       // accept result
+                                       requestor.acceptVariableName(
+                                               qualifiedPackageName,
+                                               qualifiedSourceName,
+                                               name,
+                                               name,
+                                               startPosition - offset,
+                                               endPosition - offset,
+                                               relevance);
+                                       return;
+                               }
+                       } catch(InvalidInputException e){
+                       }
+                       
+                       // compute variable name for non base type
+                       char[][] names = computeNames(sourceName, dim > 0);
+                       char[] displayName;
+                       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;
+                       }
+                       next : for(int i = 0 ; i < names.length ; i++){
+                               name = names[i];
+                               
+                               if (!CharOperation.prefixEquals(token, name, false))
+                                       continue next;
+                               
+                               // completion must be an identifier (not a keyword, ...).
+                               try{
+                                       nameScanner.setSource(name);
+                                       if(nameScanner.getNextToken() != TokenNameIdentifier)
+                                               continue next;
+                               } catch(InvalidInputException e){
+                                       continue next;
+                               }
+                               
+                               int count = 2;
+                               char[] originalName = name;
+                               for(int j = 0 ; j < excludeNames.length ; j++){
+                                       if(CharOperation.equals(name, excludeNames[j], false)) {
+                                               name = CharOperation.concat(originalName, String.valueOf(count++).toCharArray());
+                                               j = 0;
+                                       }       
+                               }
+                               
+                               int relevance = R_DEFAULT;
+                               relevance += computeRelevanceForCaseMatching(token, name);
+                               
+                               // accept result
+                               requestor.acceptVariableName(
+                                       qualifiedPackageName,
+                                       displayName,
+                                       name,
+                                       name,
+                                       startPosition - offset,
+                                       endPosition - offset,
+                                       relevance);
+                       }
+       }
+
+       private void findVariableNames(char[] name, TypeReference type , char[][] excludeNames){
+
+               if(type != null &&
+                       type.binding != null &&
+                       type.binding.problemId() == Binding.NoError){
+                       TypeBinding tb = type.binding;
+                       findVariableName(
+                               name,
+                               tb.leafComponentType().qualifiedPackageName(),
+                               tb.leafComponentType().qualifiedSourceName(),
+                               tb.leafComponentType().sourceName(),
+                               excludeNames,
+                               type.dimensions());
+               }/*     else {
+                       char[][] typeName = type.getTypeName();
+                       findVariableName(
+                               name,
+                               NoChar,
+                               CharOperation.concatWith(typeName, '.'),
+                               typeName[typeName.length - 1],
+                               excludeNames,
+                               type.dimensions());
+               }*/
+       }
+       
+       public AssistParser getParser() {
+
+               return parser;
+       }
+
+       protected void reset() {
+
+               super.reset();
+               this.knownPkgs = new HashtableOfObject(10);
+               this.knownTypes = new HashtableOfObject(10);
+       }
+
+       private void setSourceRange(int start, int end) {
+
+               this.startPosition = start;
+               this.endPosition = end + 1;
+       }
+       
+       private char[] computeBaseNames(char firstName, char[][] excludeNames){
+               char[] name = new char[]{firstName};
+               
+               for(int i = 0 ; i < excludeNames.length ; i++){
+                       if(CharOperation.equals(name, excludeNames[i], false)) {
+                               name[0]++;
+                               if(name[0] > 'z')
+                                       name[0] = 'a';
+                               if(name[0] == firstName)
+                                       return null;
+                               i = 0;
+                       }       
+               }
+               
+               return name;
+       }
+       private void computeExpectedTypes(AstNode parent, Scope scope){
+               int expectedTypeCount = 0;
+               expectedTypes = new TypeBinding[1];
+               
+               if(parent instanceof AbstractVariableDeclaration) {
+                       TypeBinding binding = ((AbstractVariableDeclaration)parent).type.binding;
+                       if(binding != null) {
+                               expectedTypes[expectedTypeCount++] = binding;
+                       }
+               } else if(parent instanceof Assignment) {
+                       TypeBinding binding = ((Assignment)parent).lhsType;
+                       if(binding != null) {
+                               expectedTypes[expectedTypeCount++] = binding;
+                       }
+               } else if(parent instanceof ReturnStatement) {
+                       MethodBinding methodBinding = ((AbstractMethodDeclaration) scope.methodScope().referenceContext).binding;
+                       TypeBinding binding = methodBinding  == null ? null : methodBinding.returnType;
+                       if(binding != null) {
+                               expectedTypes[expectedTypeCount++] = binding;
+                       }
+               }
+               
+               System.arraycopy(expectedTypes, 0, expectedTypes = new TypeBinding[expectedTypeCount], 0, expectedTypeCount);
+       }
+       private char[][] computeNames(char[] sourceName, boolean forArray){
+               char[][] names = new char[5][];
+               int nameCount = 0;
+               boolean previousIsUpperCase = false;
+               for(int i = sourceName.length - 1 ; i >= 0 ; i--){
+                       boolean isUpperCase = Character.isUpperCase(sourceName[i]);
+                       if(isUpperCase && !previousIsUpperCase){
+                               char[] name = CharOperation.subarray(sourceName,i,sourceName.length);
+                               if(name.length > 1){
+                                       if(nameCount == names.length) {
+                                               System.arraycopy(names, 0, names = new char[nameCount * 2][], 0, nameCount);
+                                       }
+                                       name[0] = Character.toLowerCase(name[0]);
+                                       
+                                       if(forArray) {
+                                               int length = name.length;
+                                               if (name[length-1] == 's'){
+                                                       System.arraycopy(name, 0, name = new char[length + 2], 0, length);
+                                                       name[length] = 'e';
+                                                       name[length+1] = 's';
+                                               } else {
+                                                       System.arraycopy(name, 0, name = new char[length + 1], 0, length);
+                                                       name[length] = 's';
+                                               }
+                                       }                                       
+                                       names[nameCount++] = name;
+                               }
+                       }
+                       previousIsUpperCase = isUpperCase;
+               }
+               if(nameCount == 0){
+                       char[] name = CharOperation.toLowerCase(sourceName);
+                       if(forArray) {
+                               int length = name.length;
+                               if (name[length-1] == 's'){
+                                       System.arraycopy(name, 0, name = new char[length + 2], 0, length);
+                                       name[length] = 'e';
+                                       name[length+1] = 's';
+                               } else {
+                                       System.arraycopy(name, 0, name = new char[length + 1], 0, length);
+                                       name[length] = 's';
+                               }
+                       }                                       
+                       names[nameCount++] = name;
+                       
+               }
+               System.arraycopy(names, 0, names = new char[nameCount][], 0, nameCount);
+               return names;
+       }
+       
+       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 boolean isEnclosed(ReferenceBinding possibleEnclosingType, ReferenceBinding type){
+               if(type.isNestedType()){
+                       ReferenceBinding enclosing = type.enclosingType();
+                       while(enclosing != null ){
+                               if(possibleEnclosingType == enclosing)
+                                       return true;
+                               enclosing = enclosing.enclosingType();
+                       }
+               }
+               return false;
+       }
+
+}