package org.eclipse.jdt.internal.core.search.matching;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;

import org.eclipse.jdt.core.*;
import org.eclipse.jdt.internal.core.index.*;
import org.eclipse.jdt.core.search.*;

import org.eclipse.jdt.internal.compiler.ast.*;
import org.eclipse.jdt.internal.compiler.lookup.*;
import org.eclipse.jdt.internal.compiler.util.*;

import org.eclipse.jdt.internal.core.index.impl.IndexInput;
import org.eclipse.jdt.internal.core.index.impl.IndexedFile;
import org.eclipse.jdt.internal.core.index.impl.BlocksIndexInput;
import org.eclipse.jdt.internal.core.search.*;
import org.eclipse.jdt.internal.core.search.indexing.*;

import java.io.*;
import java.util.*;

public abstract class SearchPattern implements ISearchPattern, IIndexConstants, IJavaSearchConstants {

	protected int matchMode;
	protected boolean isCaseSensitive;
	protected boolean needsResolve;

	/* match level */
	public static final int IMPOSSIBLE_MATCH = 0;
	public static final int POSSIBLE_MATCH = 1;
	public static final int TRUSTED_MATCH = 2;

	/* match container */
	public static final int COMPILATION_UNIT = 1;
	public static final int CLASS = 2;
	public static final int FIELD = 4;
	public static final int METHOD = 8;
	
	public static final char[][][] NOT_FOUND_DECLARING_TYPE = new char[0][][];

public SearchPattern(int matchMode, boolean isCaseSensitive) {
	this.matchMode = matchMode;
	this.isCaseSensitive = isCaseSensitive;
}
/**
 * Constructor pattern are formed by [declaringQualification.]type[(parameterTypes)]
 * e.g. java.lang.Runnable.run() void
 *		main(*)
 */
private static SearchPattern createConstructorPattern(String patternString, int limitTo, int matchMode, boolean isCaseSensitive) {

	StringTokenizer tokenizer = new StringTokenizer(patternString, " .(,)"/*nonNLS*/, true);
	final int InsideName = 1;
	final int InsideParameter = 2;
	String lastToken = null;
	
	String declaringQualification = null, typeName = null, parameterType = null;
	String[] parameterTypes = null;
	int parameterCount = -1;
	String returnType = null;
	boolean foundClosingParenthesis = false;
	int mode = InsideName;
	while (tokenizer.hasMoreTokens()){
		String token = tokenizer.nextToken();
		switch(mode){

			// read declaring type and selector
			case InsideName :
				if (token.equals("."/*nonNLS*/)){
					if (declaringQualification == null){
						if (typeName == null) return null;
						declaringQualification = typeName;
					} else {
						declaringQualification += token + typeName;
					}
					typeName = null;
				} else if (token.equals("("/*nonNLS*/)){
					parameterTypes = new String[5];
					parameterCount = 0;
					mode = InsideParameter;
				} else if (token.equals(" "/*nonNLS*/)){
					if (!(" "/*nonNLS*/.equals(lastToken) || "."/*nonNLS*/.equals(lastToken))){
						break;
					}
				} else { // name
					if (typeName != null) return null;
					typeName = token;
				}
				break;
			// read parameter types
			case InsideParameter :
				if (token.equals(" "/*nonNLS*/)){
				} else if (token.equals(","/*nonNLS*/)){
					if (parameterType == null) return null;
					if (parameterTypes.length == parameterCount){
						System.arraycopy(parameterTypes, 0, parameterTypes = new String[parameterCount*2], 0, parameterCount);
					}
					parameterTypes[parameterCount++] = parameterType;
					parameterType = null;
				} else if (token.equals (")"/*nonNLS*/)){
					foundClosingParenthesis = true;
					if (parameterType != null){
						if (parameterTypes.length == parameterCount){
							System.arraycopy(parameterTypes, 0, parameterTypes = new String[parameterCount*2], 0, parameterCount);
						}
						parameterTypes[parameterCount++] = parameterType;
					}
					break;
				} else {
					if (parameterType == null){
						parameterType = token;
					} else {
						if (!("."/*nonNLS*/.equals(lastToken) || "."/*nonNLS*/.equals(token) || "[]"/*nonNLS*/.equals(token))) return null;
						parameterType += token;
					}
				}
				break;
		}
		lastToken = token;
	}
	// parenthesis mismatch
	if (parameterCount>0 && !foundClosingParenthesis) return null;
	if (typeName == null) return null;

	char[] typeNameChars = typeName.toCharArray();
	if (typeNameChars.length == 1 && typeNameChars[0] == '*') typeNameChars = null;
		
	char[] declaringQualificationChars = null;
	if (declaringQualification != null) declaringQualificationChars = declaringQualification.toCharArray();
	char[][] parameterTypeQualifications = null, parameterTypeSimpleNames = null;

	// extract parameter types infos
	if (parameterCount >= 0){
		parameterTypeQualifications = new char[parameterCount][];
		parameterTypeSimpleNames = new char[parameterCount][];
		for (int i = 0; i < parameterCount; i++){
			char[] parameterTypePart = parameterTypes[i].toCharArray();
			int lastDotPosition = CharOperation.lastIndexOf('.', parameterTypePart);
			if (lastDotPosition >= 0){
				parameterTypeQualifications[i] = CharOperation.subarray(parameterTypePart, 0, lastDotPosition);
				if (parameterTypeQualifications[i].length == 1 && parameterTypeQualifications[i][0] == '*') parameterTypeQualifications[i] = null;
				parameterTypeSimpleNames[i] = CharOperation.subarray(parameterTypePart, lastDotPosition+1, parameterTypePart.length);
			} else {
				parameterTypeQualifications[i] = null;
				parameterTypeSimpleNames[i] = parameterTypePart;
			}
			if (parameterTypeSimpleNames[i].length == 1 && parameterTypeSimpleNames[i][0] == '*') parameterTypeSimpleNames[i] = null;
		}
	}	
	SearchPattern searchPattern = null;
	switch (limitTo){
		case IJavaSearchConstants.DECLARATIONS :
			searchPattern = new ConstructorDeclarationPattern(typeNameChars, matchMode, isCaseSensitive, declaringQualificationChars, parameterTypeQualifications, parameterTypeSimpleNames);
			break;
		case IJavaSearchConstants.REFERENCES :
			searchPattern = new ConstructorReferencePattern(typeNameChars, matchMode, isCaseSensitive, declaringQualificationChars, parameterTypeQualifications, parameterTypeSimpleNames);
			break;
		case IJavaSearchConstants.ALL_OCCURRENCES :
			searchPattern = new OrPattern(
				new ConstructorDeclarationPattern(typeNameChars, matchMode, isCaseSensitive, declaringQualificationChars, parameterTypeQualifications, parameterTypeSimpleNames),
				new ConstructorReferencePattern(typeNameChars, matchMode, isCaseSensitive, declaringQualificationChars, parameterTypeQualifications, parameterTypeSimpleNames));
			break;
	}
	return searchPattern;

}
/**
 * Field pattern are formed by [declaringType.]name[type]
 * e.g. java.lang.Runnable.run() void
 *		main(*)
 */
private static SearchPattern createFieldPattern(String patternString, int limitTo, int matchMode, boolean isCaseSensitive) {

	StringTokenizer tokenizer = new StringTokenizer(patternString, " .(,)"/*nonNLS*/, true);
	final int InsideDeclaringPart = 1;
	final int InsideType = 2;
	String lastToken = null;
	
	String declaringType = null, fieldName = null, parameterType = null;
	String type = null;
	boolean foundClosingParenthesis = false;
	int mode = InsideDeclaringPart;
	while (tokenizer.hasMoreTokens()){
		String token = tokenizer.nextToken();
		switch(mode){

			// read declaring type and fieldName
			case InsideDeclaringPart :
				if (token.equals("."/*nonNLS*/)){
					if (declaringType == null){
						if (fieldName == null) return null;
						declaringType = fieldName;
					} else {
						declaringType += token + fieldName;
					}
					fieldName = null;
				} else if (token.equals(" "/*nonNLS*/)){
					if (!(" "/*nonNLS*/.equals(lastToken) || "."/*nonNLS*/.equals(lastToken))){
						mode = InsideType;
					}
				} else { // name
					if (fieldName != null) return null;
					fieldName = token;
				}
				break;
			// read type 
			case InsideType:
				if (!token.equals(" "/*nonNLS*/)){
					if (type == null){
						type = token;
					} else {
						if (!(!("."/*nonNLS*/.equals(lastToken) || "."/*nonNLS*/.equals(token) || "[]"/*nonNLS*/.equals(token)))) return null;
						type += token;
					}
				}
		}
		lastToken = token;
	}
	if (fieldName == null) return null;

	char[] fieldNameChars = fieldName.toCharArray();
	if (fieldNameChars.length == 1 && fieldNameChars[0] == '*') fieldNameChars = null;
		
	char[] declaringTypeQualification = null, declaringTypeSimpleName = null;
	char[] typeQualification = null, typeSimpleName = null;

	// extract declaring type infos
	if (declaringType != null){
		char[] declaringTypePart = declaringType.toCharArray();
		int lastDotPosition = CharOperation.lastIndexOf('.', declaringTypePart);
		if (lastDotPosition >= 0){
			declaringTypeQualification = CharOperation.subarray(declaringTypePart, 0, lastDotPosition);
			if (declaringTypeQualification.length == 1 && declaringTypeQualification[0] == '*') declaringTypeQualification = null;
			declaringTypeSimpleName = CharOperation.subarray(declaringTypePart, lastDotPosition+1, declaringTypePart.length);
		} else {
			declaringTypeQualification = null;
			declaringTypeSimpleName = declaringTypePart;
		}
		if (declaringTypeSimpleName.length == 1 && declaringTypeSimpleName[0] == '*') declaringTypeSimpleName = null;
	}
	// extract type infos
	if (type != null){
		char[] typePart = type.toCharArray();
		int lastDotPosition = CharOperation.lastIndexOf('.', typePart);
		if (lastDotPosition >= 0){
			typeQualification = CharOperation.subarray(typePart, 0, lastDotPosition);
			if (typeQualification.length == 1 && typeQualification[0] == '*') typeQualification = null;
			typeSimpleName = CharOperation.subarray(typePart, lastDotPosition+1, typePart.length);
		} else {
			typeQualification = null;
			typeSimpleName = typePart;
		}
		if (typeSimpleName.length == 1 && typeSimpleName[0] == '*') typeSimpleName = null;
	}
	SearchPattern searchPattern = null;
	switch (limitTo){
		case IJavaSearchConstants.DECLARATIONS :
			searchPattern = new FieldDeclarationPattern(fieldNameChars, matchMode, isCaseSensitive, declaringTypeQualification, declaringTypeSimpleName, typeQualification, typeSimpleName);
			break;
		case IJavaSearchConstants.REFERENCES :
			searchPattern = new FieldReferencePattern(fieldNameChars, matchMode, isCaseSensitive, declaringTypeQualification, declaringTypeSimpleName, typeQualification, typeSimpleName);
			break;
		case IJavaSearchConstants.ALL_OCCURRENCES :
			searchPattern = new OrPattern(
				new FieldDeclarationPattern(fieldNameChars, matchMode, isCaseSensitive, declaringTypeQualification, declaringTypeSimpleName, typeQualification, typeSimpleName),
				new FieldReferencePattern(fieldNameChars, matchMode, isCaseSensitive, declaringTypeQualification, declaringTypeSimpleName, typeQualification, typeSimpleName));
			break;
	}
	return searchPattern;

}
/**
 * Method pattern are formed by [declaringType.]selector[(parameterTypes)][returnType]
 * e.g. java.lang.Runnable.run() void
 *		main(*)
 */
private static SearchPattern createMethodPattern(String patternString, int limitTo, int matchMode, boolean isCaseSensitive) {

	StringTokenizer tokenizer = new StringTokenizer(patternString, " .(,)"/*nonNLS*/, true);
	final int InsideSelector = 1;
	final int InsideParameter = 2;
	final int InsideReturnType = 3;
	String lastToken = null;
	
	String declaringType = null, selector = null, parameterType = null;
	String[] parameterTypes = null;
	int parameterCount = -1;
	String returnType = null;
	boolean foundClosingParenthesis = false;
	int mode = InsideSelector;
	while (tokenizer.hasMoreTokens()){
		String token = tokenizer.nextToken();
		switch(mode){

			// read declaring type and selector
			case InsideSelector :
				if (token.equals("."/*nonNLS*/)){
					if (declaringType == null){
						if (selector == null) return null;
						declaringType = selector;
					} else {
						declaringType += token + selector;
					}
					selector = null;
				} else if (token.equals("("/*nonNLS*/)){
					parameterTypes = new String[5];
					parameterCount = 0;
					mode = InsideParameter;
				} else if (token.equals(" "/*nonNLS*/)){
					if (!(" "/*nonNLS*/.equals(lastToken) || "."/*nonNLS*/.equals(lastToken))){
						mode = InsideReturnType;
					}
				} else { // name
					if (selector != null) return null;
					selector = token;
				}
				break;
			// read parameter types
			case InsideParameter :
				if (token.equals(" "/*nonNLS*/)){
				} else if (token.equals(","/*nonNLS*/)){
					if (parameterType == null) return null;
					if (parameterTypes.length == parameterCount){
						System.arraycopy(parameterTypes, 0, parameterTypes = new String[parameterCount*2], 0, parameterCount);
					}
					parameterTypes[parameterCount++] = parameterType;
					parameterType = null;
				} else if (token.equals (")"/*nonNLS*/)){
					foundClosingParenthesis = true;
					if (parameterType != null){
						if (parameterTypes.length == parameterCount){
							System.arraycopy(parameterTypes, 0, parameterTypes = new String[parameterCount*2], 0, parameterCount);
						}
						parameterTypes[parameterCount++] = parameterType;
					}
					mode = InsideReturnType;
				} else {
					if (parameterType == null){
						parameterType = token;
					} else {
						if (!("."/*nonNLS*/.equals(lastToken) || "."/*nonNLS*/.equals(token) || "[]"/*nonNLS*/.equals(token))) return null;
						parameterType += token;
					}
				}
				break;
			// read return type
			case InsideReturnType:
				if (!token.equals(" "/*nonNLS*/)){
					if (returnType == null){
						returnType = token;
					} else {
						if (!(!("."/*nonNLS*/.equals(lastToken) || "."/*nonNLS*/.equals(token) || "[]"/*nonNLS*/.equals(token)))) return null;
						returnType += token;
					}
				}
		}
		lastToken = token;
	}
	// parenthesis mismatch
	if (parameterCount>0 && !foundClosingParenthesis) return null;
	if (selector == null) return null;

	char[] selectorChars = selector.toCharArray();
	if (selectorChars.length == 1 && selectorChars[0] == '*') selectorChars = null;
		
	char[] declaringTypeQualification = null, declaringTypeSimpleName = null;
	char[] returnTypeQualification = null, returnTypeSimpleName = null;
	char[][] parameterTypeQualifications = null, parameterTypeSimpleNames = null;

	// extract declaring type infos
	if (declaringType != null){
		char[] declaringTypePart = declaringType.toCharArray();
		int lastDotPosition = CharOperation.lastIndexOf('.', declaringTypePart);
		if (lastDotPosition >= 0){
			declaringTypeQualification = CharOperation.subarray(declaringTypePart, 0, lastDotPosition);
			if (declaringTypeQualification.length == 1 && declaringTypeQualification[0] == '*') declaringTypeQualification = null;
			declaringTypeSimpleName = CharOperation.subarray(declaringTypePart, lastDotPosition+1, declaringTypePart.length);
		} else {
			declaringTypeQualification = null;
			declaringTypeSimpleName = declaringTypePart;
		}
		if (declaringTypeSimpleName.length == 1 && declaringTypeSimpleName[0] == '*') declaringTypeSimpleName = null;
	}
	// extract parameter types infos
	if (parameterCount >= 0){
		parameterTypeQualifications = new char[parameterCount][];
		parameterTypeSimpleNames = new char[parameterCount][];
		for (int i = 0; i < parameterCount; i++){
			char[] parameterTypePart = parameterTypes[i].toCharArray();
			int lastDotPosition = CharOperation.lastIndexOf('.', parameterTypePart);
			if (lastDotPosition >= 0){
				parameterTypeQualifications[i] = CharOperation.subarray(parameterTypePart, 0, lastDotPosition);
				if (parameterTypeQualifications[i].length == 1 && parameterTypeQualifications[i][0] == '*') parameterTypeQualifications[i] = null;
				parameterTypeSimpleNames[i] = CharOperation.subarray(parameterTypePart, lastDotPosition+1, parameterTypePart.length);
			} else {
				parameterTypeQualifications[i] = null;
				parameterTypeSimpleNames[i] = parameterTypePart;
			}
			if (parameterTypeSimpleNames[i].length == 1 && parameterTypeSimpleNames[i][0] == '*') parameterTypeSimpleNames[i] = null;
		}
	}	
	// extract return type infos
	if (returnType != null){
		char[] returnTypePart = returnType.toCharArray();
		int lastDotPosition = CharOperation.lastIndexOf('.', returnTypePart);
		if (lastDotPosition >= 0){
			returnTypeQualification = CharOperation.subarray(returnTypePart, 0, lastDotPosition);
			if (returnTypeQualification.length == 1 && returnTypeQualification[0] == '*') returnTypeQualification = null;
			returnTypeSimpleName = CharOperation.subarray(returnTypePart, lastDotPosition+1, returnTypePart.length);
		} else {
			returnTypeQualification = null;
			returnTypeSimpleName = returnTypePart;
		}
		if (returnTypeSimpleName.length == 1 && returnTypeSimpleName[0] == '*') returnTypeSimpleName = null;
	}
	SearchPattern searchPattern = null;
	switch (limitTo){
		case IJavaSearchConstants.DECLARATIONS :
			searchPattern = new MethodDeclarationPattern(selectorChars, matchMode, isCaseSensitive, declaringTypeQualification, declaringTypeSimpleName, returnTypeQualification, returnTypeSimpleName, parameterTypeQualifications, parameterTypeSimpleNames);
			break;
		case IJavaSearchConstants.REFERENCES :
			searchPattern = new MethodReferencePattern(selectorChars, matchMode, isCaseSensitive, declaringTypeQualification, declaringTypeSimpleName, returnTypeQualification, returnTypeSimpleName, parameterTypeQualifications, parameterTypeSimpleNames);
			break;
		case IJavaSearchConstants.ALL_OCCURRENCES :
			searchPattern = new OrPattern(
				new MethodDeclarationPattern(selectorChars, matchMode, isCaseSensitive, declaringTypeQualification, declaringTypeSimpleName, returnTypeQualification, returnTypeSimpleName, parameterTypeQualifications, parameterTypeSimpleNames),
				new MethodReferencePattern(selectorChars, matchMode, isCaseSensitive, declaringTypeQualification, declaringTypeSimpleName, returnTypeQualification, returnTypeSimpleName, parameterTypeQualifications, parameterTypeSimpleNames));
			break;
	}
	return searchPattern;

}
private static SearchPattern createPackagePattern(String patternString, int limitTo, int matchMode, boolean isCaseSensitive) {
	SearchPattern searchPattern = null;
	switch (limitTo){
		case IJavaSearchConstants.DECLARATIONS :
			searchPattern = new PackageDeclarationPattern(patternString.toCharArray(), matchMode, isCaseSensitive);
			break;
		case IJavaSearchConstants.REFERENCES :
			searchPattern = new PackageReferencePattern(patternString.toCharArray(), matchMode, isCaseSensitive);
			break;
		case IJavaSearchConstants.ALL_OCCURRENCES :
			searchPattern = new OrPattern(
				new PackageDeclarationPattern(patternString.toCharArray(), matchMode, isCaseSensitive),
				new PackageReferencePattern(patternString.toCharArray(), matchMode, isCaseSensitive)
			);
			break;
	}
	return searchPattern;

}
public static SearchPattern createPattern(String patternString, int searchFor, int limitTo, int matchMode, boolean isCaseSensitive) {

	if (patternString == null || patternString.length() == 0)
		return null;

	SearchPattern searchPattern = null;
	switch (searchFor) {

		case IJavaSearchConstants.TYPE:
			searchPattern = createTypePattern(patternString, limitTo, matchMode, isCaseSensitive);
			break;
		case IJavaSearchConstants.METHOD:
			searchPattern = createMethodPattern(patternString, limitTo, matchMode, isCaseSensitive);
			break;			
		case IJavaSearchConstants.CONSTRUCTOR:
			searchPattern = createConstructorPattern(patternString, limitTo, matchMode, isCaseSensitive);
			break;			
		case IJavaSearchConstants.FIELD:
			searchPattern = createFieldPattern(patternString, limitTo, matchMode, isCaseSensitive);
			break;
		case IJavaSearchConstants.PACKAGE:
			searchPattern = createPackagePattern(patternString, limitTo, matchMode, isCaseSensitive);
	}
	return searchPattern;
}
public static SearchPattern createPattern(IJavaElement element, int limitTo) {
	SearchPattern searchPattern = null;
	int lastDot;
	switch (element.getElementType()) {
		case IJavaElement.FIELD :
			IField field = (IField) element; 
			String fullDeclaringName = field.getDeclaringType().getFullyQualifiedName().replace('$', '.');;
			lastDot = fullDeclaringName.lastIndexOf('.');
			char[] declaringSimpleName = (lastDot != -1 ? fullDeclaringName.substring(lastDot + 1) : fullDeclaringName).toCharArray();
			char[] declaringQualification = lastDot != -1 ? fullDeclaringName.substring(0, lastDot).toCharArray() : NO_CHAR;
			char[] name = field.getElementName().toCharArray();
			char[] typeSimpleName;
			char[] typeQualification;
			try {
				String typeSignature = Signature.toString(field.getTypeSignature()).replace('$', '.');
				lastDot = typeSignature.lastIndexOf('.');
				typeSimpleName = (lastDot != -1 ? typeSignature.substring(lastDot + 1) : typeSignature).toCharArray();
				typeQualification = lastDot != -1 ? typeSignature.substring(0, lastDot).toCharArray() : null;
			} catch (JavaModelException e) {
				return null;
			}
			switch (limitTo) {
				case IJavaSearchConstants.DECLARATIONS :
					searchPattern = new FieldDeclarationPattern(name, EXACT_MATCH, CASE_SENSITIVE, declaringQualification, declaringSimpleName, typeQualification, typeSimpleName);
					break;
				case IJavaSearchConstants.REFERENCES :
					searchPattern = new FieldReferencePattern(name, EXACT_MATCH, CASE_SENSITIVE, declaringQualification, declaringSimpleName, typeQualification, typeSimpleName);
					break;
				case IJavaSearchConstants.ALL_OCCURRENCES :
					searchPattern = new OrPattern(
						new FieldDeclarationPattern(name, EXACT_MATCH, CASE_SENSITIVE, declaringQualification, declaringSimpleName, typeQualification, typeSimpleName), 
						new FieldReferencePattern(name, EXACT_MATCH, CASE_SENSITIVE, declaringQualification, declaringSimpleName, typeQualification, typeSimpleName));
					break;
			}
			break;
		case IJavaElement.IMPORT_DECLARATION :
			String elementName = element.getElementName();
			IImportDeclaration importDecl = (IImportDeclaration)element;
			if (importDecl.isOnDemand()) {
				lastDot = elementName.lastIndexOf('.');
				if (lastDot == -1) return null; // invalid import declaration
				searchPattern = createPackagePattern(elementName.substring(0, lastDot), limitTo, EXACT_MATCH, CASE_SENSITIVE);
			} else {
				searchPattern = createTypePattern(elementName, limitTo);
			}
			break;
		case IJavaElement.METHOD :
			IMethod method = (IMethod) element;
			boolean isConstructor;
			try {
				isConstructor = method.isConstructor();
			} catch (JavaModelException e) {
				return null;
			}
			fullDeclaringName = method.getDeclaringType().getFullyQualifiedName().replace('$', '.');
			lastDot = fullDeclaringName.lastIndexOf('.');
			declaringSimpleName = (lastDot != -1 ? fullDeclaringName.substring(lastDot + 1) : fullDeclaringName).toCharArray();
			declaringQualification = lastDot != -1 ? fullDeclaringName.substring(0, lastDot).toCharArray() : NO_CHAR;
			char[] selector = method.getElementName().toCharArray();
			char[] returnSimpleName;
			char[] returnQualification;
			try {
				String returnType = Signature.toString(method.getReturnType()).replace('$', '.');
				lastDot = returnType.lastIndexOf('.');
				returnSimpleName = (lastDot != -1 ? returnType.substring(lastDot + 1) : returnType).toCharArray();
				returnQualification = lastDot != -1 ? returnType.substring(0, lastDot).toCharArray() : null;
			} catch (JavaModelException e) {
				return null;
			}
			String[] parameterTypes = method.getParameterTypes();
			int paramCount = parameterTypes.length;
			char[][] parameterSimpleNames = new char[paramCount][];
			char[][] parameterQualifications = new char[paramCount][];
			for (int i = 0; i < paramCount; i++) {
				String signature = Signature.toString(parameterTypes[i]).replace('$', '.');
				lastDot = signature.lastIndexOf('.');
				parameterSimpleNames[i] = (lastDot != -1 ? signature.substring(lastDot + 1) : signature).toCharArray();
				parameterQualifications[i] = lastDot != -1 ? signature.substring(0, lastDot).toCharArray() : null;
			}
			switch (limitTo) {
				case IJavaSearchConstants.DECLARATIONS :
					if (isConstructor) {
						searchPattern = new ConstructorDeclarationPattern(declaringSimpleName, EXACT_MATCH, CASE_SENSITIVE, declaringQualification, parameterQualifications, parameterSimpleNames);
					} else {
						searchPattern = new MethodDeclarationPattern(selector, EXACT_MATCH, CASE_SENSITIVE, declaringQualification, declaringSimpleName, returnQualification, returnSimpleName, parameterQualifications, parameterSimpleNames);
					}
					break;
				case IJavaSearchConstants.REFERENCES :
					if (isConstructor) {
						searchPattern = new ConstructorReferencePattern(declaringSimpleName, EXACT_MATCH, CASE_SENSITIVE, declaringQualification, parameterQualifications, parameterSimpleNames);
					} else {
						searchPattern = new MethodReferencePattern(selector, EXACT_MATCH, CASE_SENSITIVE, declaringQualification, declaringSimpleName, returnQualification, returnSimpleName, parameterQualifications, parameterSimpleNames);
					}
					break;
				case IJavaSearchConstants.ALL_OCCURRENCES :
					if (isConstructor) {
						searchPattern = new OrPattern(
							new ConstructorDeclarationPattern(declaringSimpleName, EXACT_MATCH, CASE_SENSITIVE, declaringQualification, parameterQualifications, parameterSimpleNames), 
							new ConstructorReferencePattern(declaringSimpleName, EXACT_MATCH, CASE_SENSITIVE, declaringQualification, parameterQualifications, parameterSimpleNames));
					} else {
						searchPattern = new OrPattern(
							new MethodDeclarationPattern(selector, EXACT_MATCH, CASE_SENSITIVE, declaringQualification, declaringSimpleName, returnQualification, returnSimpleName, parameterQualifications, parameterSimpleNames), 
							new MethodReferencePattern(selector, EXACT_MATCH, CASE_SENSITIVE, declaringQualification, declaringSimpleName, returnQualification, returnSimpleName, parameterQualifications, parameterSimpleNames));
					}
					break;
			}
			break;
		case IJavaElement.TYPE :
			IType type = (IType) element;
			searchPattern = createTypePattern(type.getFullyQualifiedName(), limitTo);
			break;
		case IJavaElement.PACKAGE_DECLARATION :
		case IJavaElement.PACKAGE_FRAGMENT :
			searchPattern = createPackagePattern(element.getElementName(), limitTo, EXACT_MATCH, CASE_SENSITIVE);
			break;
	}
	return searchPattern;
}
private static SearchPattern createTypePattern(String fullyQualifiedName, int limitTo) {
	SearchPattern searchPattern = null;
	int lastDot = fullyQualifiedName.lastIndexOf('.');
	int lastDollar = fullyQualifiedName.lastIndexOf('$');
	if (lastDollar < lastDot) lastDollar = -1; // must be in last segment
	char[] enclosingTypeName, simpleName;
	if (lastDollar >= 0){
		enclosingTypeName = fullyQualifiedName.substring(lastDot+1, lastDollar).toCharArray();
		simpleName = fullyQualifiedName.substring(lastDollar+1, fullyQualifiedName.length()).toCharArray();
	} else {
		enclosingTypeName = new char[0];
		simpleName = (lastDot != -1 ? fullyQualifiedName.substring(lastDot + 1) : fullyQualifiedName).toCharArray();
	}
	char[] qualification = lastDot != -1 ? fullyQualifiedName.substring(0, lastDot).toCharArray() : null;
	
	switch (limitTo) {
		case IJavaSearchConstants.DECLARATIONS :
			char[][] enclosingTypeNames = CharOperation.splitOn('$', enclosingTypeName);
			searchPattern = new TypeDeclarationPattern(qualification, enclosingTypeNames, simpleName, TYPE_SUFFIX, EXACT_MATCH, CASE_SENSITIVE);
			break;
		case IJavaSearchConstants.REFERENCES :
			if (enclosingTypeName.length > 0) {
				qualification = CharOperation.concat(qualification, enclosingTypeName, '.');
			}
			searchPattern = new TypeReferencePattern(qualification, simpleName, EXACT_MATCH, CASE_SENSITIVE);
			break;
		case IJavaSearchConstants.IMPLEMENTORS : 
			searchPattern = new SuperInterfaceReferencePattern(qualification, simpleName, EXACT_MATCH, CASE_SENSITIVE);
			break;
		case IJavaSearchConstants.ALL_OCCURRENCES :
			enclosingTypeNames = CharOperation.splitOn('$', enclosingTypeName);
			searchPattern = new OrPattern(
				new TypeDeclarationPattern(qualification, enclosingTypeNames, simpleName, TYPE_SUFFIX, EXACT_MATCH, CASE_SENSITIVE), 
				new TypeReferencePattern(qualification, simpleName, EXACT_MATCH, CASE_SENSITIVE));
			break;
	}
	return searchPattern;
}
/**
 * Type pattern are formed by [package.]type
 * e.g. java.lang.Object
 *		Runnable
 *
 */
private static SearchPattern createTypePattern(String patternString, int limitTo, int matchMode, boolean isCaseSensitive) {

	StringTokenizer tokenizer = new StringTokenizer(patternString, " ."/*nonNLS*/, true);
	String type = null;
	String lastToken = null;
	while (tokenizer.hasMoreTokens()){
		String token = tokenizer.nextToken();
		if (!token.equals(" "/*nonNLS*/)){
			if (type == null){
				type = token;
			} else {
				if (!("."/*nonNLS*/.equals(lastToken) || "."/*nonNLS*/.equals(token) || "[]"/*nonNLS*/.equals(token))) return null;
				type += token;
			}
		}
		lastToken = token;
	}
	if (type == null) return null;

	char[] packageChars = null, typeChars = null;

	// extract declaring type infos
	if (type != null){
		char[] typePart = type.toCharArray();
		int lastDotPosition = CharOperation.lastIndexOf('.', typePart);
		if (lastDotPosition >= 0){
			packageChars = CharOperation.subarray(typePart, 0, lastDotPosition);
			if (packageChars.length == 1 && packageChars[0] == '*') packageChars = null;
			typeChars = CharOperation.subarray(typePart, lastDotPosition+1, typePart.length);
		} else {
			packageChars = null;
			typeChars = typePart;
		}
		if (typeChars.length == 1 && typeChars[0] == '*') typeChars = null;
	}
	SearchPattern searchPattern = null;
	switch (limitTo){
		case IJavaSearchConstants.DECLARATIONS : // cannot search for explicit member types
			searchPattern = new TypeDeclarationPattern(packageChars, null, typeChars, TYPE_SUFFIX, matchMode, isCaseSensitive);
			break;
		case IJavaSearchConstants.REFERENCES :
			searchPattern = new TypeReferencePattern(packageChars, typeChars, matchMode, isCaseSensitive);
			break;
		case IJavaSearchConstants.IMPLEMENTORS : 
			searchPattern = new SuperInterfaceReferencePattern(packageChars, typeChars, matchMode, isCaseSensitive);
			break;
		case IJavaSearchConstants.ALL_OCCURRENCES :
			searchPattern = new OrPattern(
				new TypeDeclarationPattern(packageChars, null, typeChars, TYPE_SUFFIX, matchMode, isCaseSensitive),// cannot search for explicit member types
				new TypeReferencePattern(packageChars, typeChars, matchMode, isCaseSensitive));
			break;
	}
	return searchPattern;

}
protected abstract void decodeIndexEntry(IEntryResult entryResult);
/**
 * Feed the requestor according to the current search pattern
 */
public abstract void feedIndexRequestor(IIndexSearchRequestor requestor, int detailLevel, int[] references, IndexInput input, IJavaSearchScope scope)  throws IOException ;
/**
 * Query a given index for matching entries. 
 */
public void findIndexMatches(IIndex index, IIndexSearchRequestor requestor, int detailLevel, IProgressMonitor progressMonitor, IJavaSearchScope scope) throws IOException {

	if (progressMonitor != null && progressMonitor.isCanceled()) throw new OperationCanceledException();

	IndexInput input = new BlocksIndexInput(index.getIndexFile());
	try {
		input.open();
		findIndexMatches(input, requestor, detailLevel, progressMonitor,scope);
	} finally {
		input.close();
	}
}
/**
 * Query a given index for matching entries. 
 */
public void findIndexMatches(IndexInput input, IIndexSearchRequestor requestor, int detailLevel, IProgressMonitor progressMonitor, IJavaSearchScope scope) throws IOException {

	if (progressMonitor != null && progressMonitor.isCanceled()) throw new OperationCanceledException();
	
	/* narrow down a set of entries using prefix criteria */
	IEntryResult[] entries = input.queryEntriesPrefixedBy(indexEntryPrefix());
	if (entries == null) return;
	
	/* only select entries which actually match the entire search pattern */
	for (int i = 0, max = entries.length; i < max; i++){

		if (progressMonitor != null && progressMonitor.isCanceled()) throw new OperationCanceledException();

		/* retrieve and decode entry */	
		IEntryResult entry = entries[i];
		decodeIndexEntry(entry);
		if (matchIndexEntry()){
			feedIndexRequestor(requestor, detailLevel, entry.getFileReferences(), input, scope);
		}
	}
}
/**
 * Answers the suitable prefix that should be used in order
 * to query indexes for the corresponding item.
 * The more accurate the prefix and the less false hits will have
 * to be eliminated later on.
 */
public abstract char[] indexEntryPrefix();
/**
 * Returns the type of container of this pattern, i.e. is it in compilation unit,
 * in class declarations, field declarations, or in method declarations.
 */
protected abstract int matchContainer();
/**
 * Finds out whether the given resolved ast node matches this search pattern.
 */
public boolean matches(AstNode node) {
	return this.matches(node, true);
}
/**
 * Returns whether this pattern matches the given node.
 * Look at resolved information only if specified.
 */
protected abstract boolean matches(AstNode node, boolean resolve);
/**
 * Finds out whether the given binding matches this search pattern.
 * Default is to return false.
 */
public boolean matches(Binding binding) {
	return false;
}
/**
 * Finds out whether the given binary info matches this search pattern.
 * Default is to return false.
 */
public boolean matchesBinary(Object binaryInfo, Object enclosingBinaryInfo) {
	return false;
}
/**
 * Returns whether the given name matches the given pattern.
 */
protected boolean matchesName(char[] pattern, char[] name) {
	if (name != null){
		switch (this.matchMode) {
			case EXACT_MATCH :
				return CharOperation.equals(pattern, name, this.isCaseSensitive);
			case PREFIX_MATCH :
				return CharOperation.prefixEquals(pattern, name, this.isCaseSensitive);
			case PATTERN_MATCH :
				return CharOperation.match(pattern, name, this.isCaseSensitive);
		}
	}
	return false;
}
/**
 * Returns whether the given type binding matches the given simple name pattern 
 * and qualification pattern.
 */
protected boolean matchesType(char[] simpleNamePattern, char[] qualificationPattern, char[] fullyQualifiedTypeName) {
	char[] pattern;
	if (simpleNamePattern == null) {
		if (qualificationPattern == null) {
			pattern = ONE_STAR;
		} else {
			pattern = CharOperation.concat(qualificationPattern, ONE_STAR, '.');
		}
	} else {
		if (qualificationPattern == null) {
			pattern = CharOperation.concat(ONE_STAR, simpleNamePattern);
		} else {
			pattern = CharOperation.concat(qualificationPattern, simpleNamePattern, '.');
		}
	}
	return 
		CharOperation.match(
			pattern,
			fullyQualifiedTypeName,
			this.isCaseSensitive
		);
}
/**
 * Returns whether the given type binding matches the given simple name pattern 
 * and qualification pattern.
 */
protected boolean matchesType(char[] simpleNamePattern, char[] qualificationPattern, TypeBinding type) {
	if (type == null) return false; 
	return 
		this.matchesType(
			simpleNamePattern, 
			qualificationPattern, 
			type.qualifiedPackageName().length == 0 ? 
				type.qualifiedSourceName() : 
				CharOperation.concat(type.qualifiedPackageName(), type.qualifiedSourceName(), '.')
		);
}
/**
 * Checks whether an entry matches the current search pattern
 */
protected abstract boolean matchIndexEntry();
/**
 * Finds out whether the given ast node matches this search pattern.
 * Returns IMPOSSIBLE_MATCH if it doesn't.
 * Returns TRUSTED_MATCH if it matches exactly this search pattern (ie. 
 * it doesn't need to be resolved or it has already been resolved.)
 * Returns POSSIBLE_MATCH if it potentially matches 
 * this search pattern and it needs to be resolved to get more information.
 */
public int matchLevel(AstNode node) {
	if (this.matches(node, false)) {
		if (this.needsResolve) {
			return POSSIBLE_MATCH;
		} else {
			return TRUSTED_MATCH;
		}
	}
	return IMPOSSIBLE_MATCH;
}
/**
 * Reports the match of the given reference.
 */
protected void matchReportReference(AstNode reference, IJavaElement element, int accuracy, MatchLocator locator) throws CoreException {
	// default is to report a match on the whole node.
	locator.report(reference.sourceStart, reference.sourceEnd, element, accuracy);
}
/**
 * Add square brackets to the given simple name
 */
protected char[] toArrayName(char[] simpleName, int dimensions) {
	if (dimensions == 0) return simpleName;
	char[] result = new char[simpleName.length + dimensions * 2];
	for (int i = 0; i < dimensions; i++) {
		result[simpleName.length + i*2] = '[';
		result[simpleName.length + i*2 + 1] = ']';
	}
	return result;
}
public String toString(){
	return "SearchPattern"/*nonNLS*/;
}

/**
 * Collects the super type names of the given declaring type.
 * Returns NOT_FOUND_DECLARING_TYPE if the declaring type was not found.
 * Returns null if the declaring type pattern doesn't require an exact match.
 */
protected char[][][] collectSuperTypeNames(char[] declaringQualification, char[] declaringSimpleName, int matchMode, LookupEnvironment env) {

	char[][] declaringTypeName = null;
	if (declaringQualification != null 
			&& declaringSimpleName != null
			&& matchMode == EXACT_MATCH) {
		char[][] qualification = CharOperation.splitOn('.', declaringQualification);
		declaringTypeName = CharOperation.arrayConcat(qualification, declaringSimpleName);
	}
	if (declaringTypeName != null) {
		for (int i = 0, max = declaringTypeName.length; i < max; i++) {
			ReferenceBinding matchingDeclaringType = env.askForType(declaringTypeName);
			if (matchingDeclaringType != null 
				&& (matchingDeclaringType.isValidBinding()
					|| matchingDeclaringType.problemId() != ProblemReasons.NotFound)) {
				return this.collectSuperTypeNames(matchingDeclaringType);
			}
			// if nothing is in the cache, it could have been a member type (A.B.C.D --> A.B.C$D)
			int last = declaringTypeName.length - 1;
			if (last == 0) break; 
			declaringTypeName[last-1] = CharOperation.concat(declaringTypeName[last-1], declaringTypeName[last], '$'); // try nested type
			declaringTypeName = CharOperation.subarray(declaringTypeName, 0, last);
		}
		return NOT_FOUND_DECLARING_TYPE; // the declaring type was not found 
	} else {
		// non exact match: use the null value so that matches is more tolerant
		return null;
	}
}

/**
 * Collects the names of all the supertypes of the given type.
 */
private char[][][] collectSuperTypeNames(ReferenceBinding type) {

	// superclass
	char[][][] superClassNames = null;
	ReferenceBinding superclass = type.superclass();
	if (superclass != null) {
		superClassNames = this.collectSuperTypeNames(superclass);
	}

	// interfaces
	char[][][][] superInterfaceNames = null;
	int superInterfaceNamesLength = 0;
	ReferenceBinding[] interfaces = type.superInterfaces();
	if (interfaces != null) {
		superInterfaceNames = new char[interfaces.length][][][];
		for (int i = 0; i < interfaces.length; i++) {
			superInterfaceNames[i] = this.collectSuperTypeNames(interfaces[i]);
			superInterfaceNamesLength += superInterfaceNames[i].length;
		}
	}

	int length = 
		(superclass == null ? 0 : 1)
		+ (superClassNames == null ? 0 : superClassNames.length)
		+ (interfaces == null ? 0 : interfaces.length)
		+ superInterfaceNamesLength;
	char[][][] result = new char[length][][];
	int index = 0;
	if (superclass != null) {
		result[index++] = superclass.compoundName;
		if (superClassNames != null) {
			System.arraycopy(superClassNames, 0, result, index, superClassNames.length);
			index += superClassNames.length;
		}
	}
	if (interfaces != null) {
		for (int i = 0, max = interfaces.length; i < max; i++) {
			result[index++] = interfaces[i].compoundName;
			if (superInterfaceNames != null) {
				System.arraycopy(superInterfaceNames[i], 0, result, index, superInterfaceNames[i].length);
				index += superInterfaceNames[i].length;
			}
		}
	}
	
	return result;
}

/**
 * Initializes this search pattern from the given lookup environment.
 * Returns whether it could be initialized.
 */ 
public boolean initializeFromLookupEnvironment(LookupEnvironment env) {
	return true;
}

/**
 * Returns whether the given reference type binding matches or is a subtype of a type
 * that matches the given simple name pattern and qualification pattern.
 */
protected boolean matchesAsSubtype(ReferenceBinding type, char[] simpleNamePattern, char[] qualificationPattern) {
	// matches type
	if (this.matchesType(simpleNamePattern, qualificationPattern, type))
		return true;
	
	// matches superclass
	ReferenceBinding superclass = type.superclass();
	if (superclass != null) {
		if (this.matchesAsSubtype(superclass, simpleNamePattern, qualificationPattern))
			return true;
	}

	// matches interfaces
	ReferenceBinding[] interfaces = type.superInterfaces();
	for (int i = 0; i < interfaces.length; i++) {
		if (this.matchesAsSubtype(interfaces[i], simpleNamePattern, qualificationPattern))
			return true;
	}

	return false;
}

/**
 * Returns whether one of the given declaring types is the given receiver type.
 */
protected boolean matchesType(char[][][] declaringTypes, ReferenceBinding receiverType) {
	if (declaringTypes == null) {
		return true; // we were not able to compute the declaring types, default to true
	} else {
		for (int i = 0, max = declaringTypes.length; i < max; i++) {
			if (CharOperation.equals(declaringTypes[i], receiverType.compoundName)) {
				return true;
			}
		}
		return false;
	}
}
}
