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

 *******************************************************************************/
package org.eclipse.dltk.core.search;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.dltk.ast.declarations.TypeDeclaration;
import org.eclipse.dltk.compiler.CharOperation;
import org.eclipse.dltk.core.DLTKCore;
import org.eclipse.dltk.core.DLTKLanguageManager;
import org.eclipse.dltk.core.IDLTKLanguageToolkit;
import org.eclipse.dltk.core.IMember;
import org.eclipse.dltk.core.IModelElement;
import org.eclipse.dltk.core.IProjectFragment;
import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.dltk.core.IType;
import org.eclipse.dltk.core.ModelException;
import org.eclipse.dltk.core.WorkingCopyOwner;
import org.eclipse.dltk.core.search.indexing.IIndexConstants;
import org.eclipse.dltk.core.search.indexing.IndexManager;
import org.eclipse.dltk.core.search.matching.MatchLocator;
import org.eclipse.dltk.internal.compiler.env.AccessRestriction;
import org.eclipse.dltk.internal.compiler.env.AccessRuleSet;
import org.eclipse.dltk.internal.core.DefaultWorkingCopyOwner;
import org.eclipse.dltk.internal.core.ModelManager;
import org.eclipse.dltk.internal.core.ScriptProject;
import org.eclipse.dltk.internal.core.SourceModule;
import org.eclipse.dltk.internal.core.search.DLTKSearchDocument;
import org.eclipse.dltk.internal.core.search.DLTKSearchScope;
import org.eclipse.dltk.internal.core.search.DLTKSearchTypeNameMatch;
import org.eclipse.dltk.internal.core.search.HierarchyScope;
import org.eclipse.dltk.internal.core.search.IRestrictedAccessTypeRequestor;
import org.eclipse.dltk.internal.core.search.IndexQueryRequestor;
import org.eclipse.dltk.internal.core.search.PathCollector;
import org.eclipse.dltk.internal.core.search.PatternSearchJob;
import org.eclipse.dltk.internal.core.search.matching.DLTKSearchPattern;
import org.eclipse.dltk.internal.core.search.matching.QualifiedTypeDeclarationPattern;
import org.eclipse.dltk.internal.core.search.matching.TypeDeclarationPattern;
import org.eclipse.dltk.internal.core.util.Messages;
import org.eclipse.dltk.internal.core.util.Util;

/**
 * Search basic engine. Public search engine now uses basic engine
 * functionalities. Note that serch basic engine does not implement deprecated
 * functionalities...
 */
public class BasicSearchEngine {

	/*
	 * A default parseor to parse non-reconciled working copies
	 */

	/*
	 * A list of working copies that take precedence over their original
	 * compilation units.
	 */
	private ISourceModule[] workingCopies;

	/*
	 * A working copy owner whose working copies will take precedent over their
	 * original compilation units.
	 */
	private WorkingCopyOwner workingCopyOwner;

	/**
	 * For tracing purpose.
	 */
	public static boolean VERBOSE = DLTKCore.VERBOSE_SEARCH;

	/*
	 * Creates a new search basic engine.
	 */
	public BasicSearchEngine() {
		// will use working copies of PRIMARY owner
	}

	/**
	 * @see SearchEngine#SearchEngine(ISourceModule[]) for detailed comment.
	 */
	public BasicSearchEngine(ISourceModule[] workingCopies) {
		this.workingCopies = workingCopies;
	}

	char convertTypeKind(int typeDeclarationKind) {
		switch (typeDeclarationKind) {
		case TypeDeclaration.D_CLASS:
			return IIndexConstants.TYPE_SUFFIX;
		default:
			return IIndexConstants.TYPE_SUFFIX;
		}
	}

	/**
	 * @see SearchEngine#SearchEngine(WorkingCopyOwner) for detailed comment.
	 */
	public BasicSearchEngine(WorkingCopyOwner workingCopyOwner) {
		this.workingCopyOwner = workingCopyOwner;
	}

	/**
	 * @see SearchEngine#createHierarchyScope(IType) for detailed comment.
	 */
	public static IDLTKSearchScope createHierarchyScope(IType type)
			throws ModelException {
		return createHierarchyScope(type, DefaultWorkingCopyOwner.PRIMARY);
	}

	/**
	 * @see SearchEngine#createHierarchyScope(IType,WorkingCopyOwner) for
	 *      detailed comment.
	 */
	public static IDLTKSearchScope createHierarchyScope(IType type,
			WorkingCopyOwner owner) throws ModelException {
		IDLTKLanguageToolkit toolkit;
		try {
			toolkit = DLTKLanguageManager.getLanguageToolkit(type);
		} catch (CoreException e) {
			if (DLTKCore.DEBUG) {
				e.printStackTrace();
			}
			return null;
		}
		return new HierarchyScope(toolkit, type, owner);
	}

	/**
	 * @see SearchEngine#createSearchScope(IModelElement[]) for detailed
	 *      comment.
	 */
	public static IDLTKSearchScope createSearchScope(IModelElement[] elements) {
		return createSearchScope(elements, true);
	}

	/**
	 * @see SearchEngine#createSearchScope(IModelElement[], boolean) for
	 *      detailed comment.
	 */
	public static IDLTKSearchScope createSearchScope(IModelElement[] elements,
			boolean includeReferencedProjects) {
		int includeMask = IDLTKSearchScope.SOURCES
				| IDLTKSearchScope.APPLICATION_LIBRARIES
				| IDLTKSearchScope.SYSTEM_LIBRARIES;
		if (includeReferencedProjects) {
			includeMask |= IDLTKSearchScope.REFERENCED_PROJECTS;
		}
		return createSearchScope(elements, includeMask);
	}

	/**
	 * @see SearchEngine#createSearchScope(IModelElement[], int) for detailed
	 *      comment.
	 */
	public static IDLTKSearchScope createSearchScope(IModelElement[] elements,
			int includeMask) {
		IDLTKLanguageToolkit toolkit = null;
		if (elements.length > 0) {
			try {
				toolkit = DLTKLanguageManager.getLanguageToolkit(elements[0]);
			} catch (CoreException e) {
				if (DLTKCore.DEBUG) {
					e.printStackTrace();
				}
				return null;
			}
		}
		if (toolkit == null) {
			return null;
		}
		DLTKSearchScope scope = new DLTKSearchScope(toolkit);
		HashSet visitedProjects = new HashSet(2);
		for (int i = 0; i < elements.length; i++) {
			IModelElement element = elements[i];
			if (element != null) {
				try {
					if (element instanceof ScriptProject) {
						scope.add((ScriptProject) element, includeMask,
								visitedProjects);
					} else {
						scope.add(element);
					}
				} catch (ModelException e) {
					// ignore
				}
			}
		}
		return scope;
	}

	/**
	 * @see SearchEngine#createTypeNameMatch(IType, int) for detailed comment.
	 */
	public static TypeNameMatch createTypeNameMatch(IType type, int modifiers) {
		return new DLTKSearchTypeNameMatch(type, modifiers);
	}

	/**
	 * @see SearchEngine#createWorkspaceScope() for detailed comment.
	 */
	public static IDLTKSearchScope createWorkspaceScope(
			IDLTKLanguageToolkit toolkit) {
		return ModelManager.getModelManager().getWorkspaceScope(toolkit);
	}

	/**
	 * Searches for matches to a given query. Search queries can be created
	 * using helper methods (from a String pattern or a Script element) and
	 * encapsulate the description of what is being searched (for example,
	 * search method declarations in a case sensitive way).
	 *
	 * @param scope
	 *            the search result has to be limited to the given scope
	 * @param requestor
	 *            a callback object to which each match is reported
	 */
	void findMatches(SearchPattern pattern, SearchParticipant[] participants,
			IDLTKSearchScope scope, SearchRequestor requestor,
			IProgressMonitor monitor) throws CoreException {
		if (monitor != null && monitor.isCanceled()) {
			throw new OperationCanceledException();
		}

	
		if (VERBOSE) {
			Util.verbose("Searching for pattern: " + pattern.toString()); //$NON-NLS-1$
			Util.verbose(scope.toString());
		}
		if (participants == null) {
			if (VERBOSE) {
				Util.verbose("No participants => do nothing!"); //$NON-NLS-1$
			}
			return;
		}
		int length = participants.length;
		if (monitor != null)
			monitor.beginTask(Messages.engine_searching, 100 * length); 

		IndexManager indexManager = ModelManager.getModelManager()
				.getIndexManager();
		try {
			requestor.beginReporting();
			for (int i = 0; i < participants.length; i++) {
				SearchParticipant participant = participants[i];
				if (monitor != null && monitor.isCanceled()) {
					throw new OperationCanceledException();
				}

				try {
					if (monitor != null) monitor.subTask(Messages.bind(Messages.engine_searching_indexing, new String[] {participant.getDescription()})); 
					participant.beginSearching();
					requestor.enterParticipant(participant);
					PathCollector pathCollector = new PathCollector();
					indexManager.performConcurrentJob(new PatternSearchJob(
							pattern, participant, scope, pathCollector),
							IDLTKSearchConstants.WAIT_UNTIL_READY_TO_SEARCH,
							monitor==null ? null : new SubProgressMonitor(monitor, 50));
					if (monitor != null && monitor.isCanceled()) throw new OperationCanceledException();

					// locate index matches if any (note that all search matches
					// could have been issued during index querying)
					if (monitor != null) monitor.subTask(Messages.bind(Messages.engine_searching_matching, new String[] {participant.getDescription()})); 
					String[] indexMatchPaths = pathCollector.getPaths();
					if (indexMatchPaths != null) {
						pathCollector = null; // release
						int indexMatchLength = indexMatchPaths.length;
						SearchDocument[] indexMatches = new SearchDocument[indexMatchLength];
						for (int j = 0; j < indexMatchLength; j++) {
							indexMatches[j] = participant
									.getDocument(indexMatchPaths[j]);
						}
						SearchDocument[] matches = MatchLocator
								.addWorkingCopies(pattern, indexMatches,
										getWorkingCopies(), participant);
						// TODO: This is Quick fix... Dublicates of Interpreter
						// libraris, should be handled not here...
						if (DLTKCore.DEBUG) {
							System.err
									.println("This is Quick fix... Dublicates of Interpreter libraris, should be handled not here..."); //$NON-NLS-1$
						}
						List paths = new ArrayList();
						List filteredMatches = new ArrayList();
						for (int q = 0; q < matches.length; ++q) {
							IPath path = new Path(matches[q].getPath());
							if (!paths.contains(path)) {
								paths.add(path);
								filteredMatches.add(matches[q]);
							}
						}
						SearchDocument[] fmatches = (SearchDocument[]) filteredMatches
								.toArray(new SearchDocument[filteredMatches
										.size()]);
						participant.locateMatches(fmatches, pattern, scope,
								requestor, monitor==null ? null : new SubProgressMonitor(monitor, 50));
					}
				} catch (Exception e) {
					e.printStackTrace();
				} finally {
					requestor.exitParticipant(participant);
					participant.doneSearching();
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			requestor.endReporting();
			if (monitor != null) {
				monitor.done();
			}
		}
	}

	List findMatchesSourceOnly(SearchPattern pattern,
			SearchParticipant[] participants, IDLTKSearchScope scope,
			IProgressMonitor monitor) throws CoreException {
		if (monitor != null && monitor.isCanceled()) {
			throw new OperationCanceledException();
		}

		/* initialize progress monitor */
		if (monitor != null) {
			monitor.beginTask(Messages.engine_searching, 100);
		}
		if (VERBOSE) {
			Util.verbose("Searching for pattern: " + pattern.toString()); //$NON-NLS-1$
			Util.verbose(scope.toString());
		}
		if (participants == null) {
			if (VERBOSE) {
				Util.verbose("No participants => do nothing!"); //$NON-NLS-1$
			}
			return null;
		}

		IndexManager indexManager = ModelManager.getModelManager()
				.getIndexManager();
		try {
			List documents = new ArrayList();
			for (int i = 0; i < participants.length; i++) {
				SearchParticipant participant = participants[i];
				if (monitor != null && monitor.isCanceled()) {
					throw new OperationCanceledException();
				}

				SubProgressMonitor subMonitor = monitor == null ? null
						: new SubProgressMonitor(monitor, 1000);
				if (subMonitor != null) {
					subMonitor.beginTask("", 1000); //$NON-NLS-1$
				}
				try {
					if (subMonitor != null) {
						subMonitor.subTask(Messages.bind(
								Messages.engine_searching_indexing,
								new String[] { participant.getDescription() }));
					}
					participant.beginSearching();
					PathCollector pathCollector = new PathCollector();
					indexManager.performConcurrentJob(new PatternSearchJob(
							pattern, participant, scope, pathCollector),
							IDLTKSearchConstants.WAIT_UNTIL_READY_TO_SEARCH,
							subMonitor);
					if (monitor != null && monitor.isCanceled()) {
						throw new OperationCanceledException();
					}

					// locate index matches if any (note that all search matches
					// could have been issued during index querying)
					if (subMonitor != null) {
						subMonitor.subTask(Messages.bind(
								Messages.engine_searching_matching,
								new String[] { participant.getDescription() }));
					}
					String[] indexMatchPaths = pathCollector.getPaths();
					if (indexMatchPaths != null) {
						pathCollector = null; // release
						int indexMatchLength = indexMatchPaths.length;
						SearchDocument[] indexMatches = new SearchDocument[indexMatchLength];
						for (int j = 0; j < indexMatchLength; j++) {
							indexMatches[j] = participant
									.getDocument(indexMatchPaths[j]);
						}
						SearchDocument[] matches = MatchLocator
								.addWorkingCopies(pattern, indexMatches,
										getWorkingCopies(), participant);
						ISourceModule[] modules = participant.locateModules(
								matches, pattern, scope, subMonitor);
						for (int k = 0; k < modules.length; ++k) {
							if (!documents.contains(modules[k])) {
								documents.add(modules[k]);
							}
						}
					}
				} catch (Exception e) {
					e.printStackTrace();
				} finally {
					participant.doneSearching();
				}
				return documents;
			}

		} catch (Exception e) {
			if (DLTKCore.DEBUG) {
				e.printStackTrace();
			}
		} finally {
			if (monitor != null) {
				monitor.done();
			}
		}
		return null;
	}

	/**
	 * Returns a new default Script search participant.
	 *
	 * @return a new default Script search participant
	 *
	 */
	public static SearchParticipant getDefaultSearchParticipant() {
		return new DLTKSearchParticipant();
	}

	/**
	 * @param matchRule
	 */
	public static String getMatchRuleString(final int matchRule) {
		if (matchRule == 0) {
			return "R_EXACT_MATCH"; //$NON-NLS-1$
		}
		StringBuffer buffer = new StringBuffer();
		for (int i = 1; i <= 8; i++) {
			int bit = matchRule & (1 << (i - 1));
			if (bit != 0 && buffer.length() > 0) {
				buffer.append(" | "); //$NON-NLS-1$
			}
			switch (bit) {
			case SearchPattern.R_PREFIX_MATCH:
				buffer.append("R_PREFIX_MATCH"); //$NON-NLS-1$
				break;
			case SearchPattern.R_CASE_SENSITIVE:
				buffer.append("R_CASE_SENSITIVE"); //$NON-NLS-1$
				break;
			case SearchPattern.R_EQUIVALENT_MATCH:
				buffer.append("R_EQUIVALENT_MATCH"); //$NON-NLS-1$
				break;
			case SearchPattern.R_ERASURE_MATCH:
				buffer.append("R_ERASURE_MATCH"); //$NON-NLS-1$
				break;
			case SearchPattern.R_FULL_MATCH:
				buffer.append("R_FULL_MATCH"); //$NON-NLS-1$
				break;
			case SearchPattern.R_PATTERN_MATCH:
				buffer.append("R_PATTERN_MATCH"); //$NON-NLS-1$
				break;
			case SearchPattern.R_REGEXP_MATCH:
				buffer.append("R_REGEXP_MATCH"); //$NON-NLS-1$
				break;
			case SearchPattern.R_CAMELCASE_MATCH:
				buffer.append("R_CAMELCASE_MATCH"); //$NON-NLS-1$
				break;
			}
		}
		return buffer.toString();
	}

	/**
	 * Return kind of search corresponding to given value.
	 *
	 * @param searchFor
	 */
	public static String getSearchForString(final int searchFor) {
		switch (searchFor) {
		case IDLTKSearchConstants.TYPE:
			return ("TYPE"); //$NON-NLS-1$
		case IDLTKSearchConstants.METHOD:
			return ("METHOD"); //$NON-NLS-1$
			// case IDLTKSearchConstants.PACKAGE:
			// return ("PACKAGE"); //$NON-NLS-1$
			// case IDLTKSearchConstants.CONSTRUCTOR:
			// return ("CONSTRUCTOR"); //$NON-NLS-1$
		case IDLTKSearchConstants.FIELD:
			return ("FIELD"); //$NON-NLS-1$
		case IDLTKSearchConstants.ANNOTATION_TYPE:
			return ("ANNOTATION_TYPE"); //$NON-NLS-1$
		}
		return "UNKNOWN"; //$NON-NLS-1$
	}

	// private Parser getParser() {
	// if (this.parser == null) {
	// this.compilerOptions = new CompilerOptions(JavaCore.getOptions());
	// ProblemReporter problemReporter =
	// new ProblemReporter(
	// DefaultErrorHandlingPolicies.proceedWithAllProblems(),
	// this.compilerOptions,
	// new DefaultProblemFactory());
	// this.parser = new Parser(problemReporter, true);
	// }
	// return this.parser;
	// }

	/*
	 * Returns the list of working copies used by this search engine. Returns
	 * null if none.
	 */
	private ISourceModule[] getWorkingCopies() {
		ISourceModule[] copies;
		if (this.workingCopies != null) {
			if (this.workingCopyOwner == null) {
				copies = ModelManager.getModelManager()
						.getWorkingCopies(DefaultWorkingCopyOwner.PRIMARY,
								false/* don't add primary WCs a second time */);
				if (copies == null) {
					copies = this.workingCopies;
				} else {
					HashMap pathToCUs = new HashMap();
					for (int i = 0; i < copies.length; i++) {
						ISourceModule unit = (ISourceModule) copies[i];
						pathToCUs.put(unit.getPath(), unit);
						
					}
					for (int i = 0; i < this.workingCopies.length; i++) {
						ISourceModule unit = this.workingCopies[i];
						pathToCUs.put(unit.getPath(), unit);
					}
					int length = pathToCUs.size();
					copies = new ISourceModule[length];
					pathToCUs.values().toArray(copies);
				}
			} else {
				copies = this.workingCopies;
			}
		} else if (this.workingCopyOwner != null) {
			copies = ModelManager.getModelManager().getWorkingCopies(
					this.workingCopyOwner, true/* add primary WCs */);
		} else {
			copies = ModelManager
					.getModelManager()
					.getWorkingCopies(DefaultWorkingCopyOwner.PRIMARY, false/*
																			 * don't
																			 * add
																			 * primary
																			 * WCs
																			 * a
																			 * second
																			 * time
																			 */);
		}
		if (copies == null) {
			return null;
		}

		// filter out primary working copies that are saved
		ISourceModule[] result = null;
		int length = copies.length;
		int index = 0;
		for (int i = 0; i < length; i++) {
			SourceModule copy = (SourceModule) copies[i];
			try {
				if (!copy.isPrimary() || copy.hasUnsavedChanges()
						|| copy.hasResourceChanged()) {
					if (result == null) {
						result = new ISourceModule[length];
					}
					result[index++] = copy;
				}
			} catch (ModelException e) {
				// copy doesn't exist: ignore
			}
		}
		if (index != length && result != null) {
			System.arraycopy(result, 0, result = new ISourceModule[index], 0,
					index);
		}
		return result;
	}

	/*
	 * Returns the list of working copies used to do the search on the given
	 * Script element.
	 */
	private ISourceModule[] getWorkingCopies(IModelElement element) {
		if (element instanceof IMember) {
			ISourceModule cu = ((IMember) element).getSourceModule();
			if (cu != null && cu.isWorkingCopy()) {
				ISourceModule[] copies = getWorkingCopies();
				int length = copies == null ? 0 : copies.length;
				if (length > 0) {
					ISourceModule[] newWorkingCopies = new ISourceModule[length + 1];
					System.arraycopy(copies, 0, newWorkingCopies, 0, length);
					newWorkingCopies[length] = cu;
					return newWorkingCopies;
				}
				return new ISourceModule[] { cu };
			}
		}
		return getWorkingCopies();
	}

	boolean match(char patternTypeSuffix, int modifiers) {
		switch (patternTypeSuffix) {
		case IIndexConstants.TYPE_SUFFIX:
			return true; // TODO: add conditions here when needed
			// case IIndexConstants.ANNOTATION_TYPE_SUFFIX :
			// return (modifiers & Flags.AccAnnotation) != 0;
		}
		return true;
	}

	boolean match(char patternTypeSuffix, char[] patternPkg,
			char[] patternTypeName, int matchRule, int typeKind, char[] typeName) {

		boolean isCaseSensitive = (matchRule & SearchPattern.R_CASE_SENSITIVE) != 0;
		// if (patternPkg != null && !CharOperation.equals(patternPkg, pkg,
		// isCaseSensitive))
		// return false;

		if (patternTypeName != null) {
			boolean isCamelCase = (matchRule & SearchPattern.R_CAMELCASE_MATCH) != 0;
			int matchMode = matchRule & DLTKSearchPattern.MATCH_MODE_MASK;
			if (!isCaseSensitive && !isCamelCase) {
				patternTypeName = CharOperation.toLowerCase(patternTypeName);
			}
			boolean matchFirstChar = !isCaseSensitive
					|| patternTypeName[0] == typeName[0];
			if (isCamelCase && matchFirstChar
					&& CharOperation.camelCaseMatch(patternTypeName, typeName)) {
				return true;
			}
			switch (matchMode) {
			case SearchPattern.R_EXACT_MATCH:
				if (!isCamelCase) {
					return matchFirstChar
							&& CharOperation.equals(patternTypeName, typeName,
									isCaseSensitive);
				}
				// fall through next case to match as prefix if camel case
				// failed
			case SearchPattern.R_PREFIX_MATCH:
				return matchFirstChar
						&& CharOperation.prefixEquals(patternTypeName,
								typeName, isCaseSensitive);
			case SearchPattern.R_PATTERN_MATCH:
				return CharOperation.match(patternTypeName, typeName,
						isCaseSensitive);
			case SearchPattern.R_REGEXP_MATCH:
				// TODO (frederic) implement regular expression match
				break;
			}
		}
		return true;

	}

	/**
	 * Searches for matches of a given search pattern. Search patterns can be
	 * created using helper methods (from a String pattern or a Script element)
	 * and encapsulate the description of what is being searched (for example,
	 * search method declarations in a case sensitive way).
	 *
	 * @see SearchEngine#search(SearchPattern, SearchParticipant[],
	 *      IJavaSearchScope, SearchRequestor, IProgressMonitor) for detailed
	 *      comment
	 */
	public void search(SearchPattern pattern, SearchParticipant[] participants,
			IDLTKSearchScope scope, SearchRequestor requestor,
			IProgressMonitor monitor) throws CoreException {
		if (VERBOSE) {
			Util
					.verbose("BasicSearchEngine.search(SearchPattern, SearchParticipant[], IJavaSearchScope, SearchRequestor, IProgressMonitor)"); //$NON-NLS-1$
		}
		findMatches(pattern, participants, scope, requestor, monitor);
	}

	/**
	 * Searches for matches of a given search pattern. Search patterns can be
	 * created using helper methods (from a String pattern or a Script element)
	 * and encapsulate the description of what is being searched (for example,
	 * search method declarations in a case sensitive way).
	 *
	 * @see SearchEngine#search(SearchPattern, SearchParticipant[],
	 *      IJavaSearchScope, SearchRequestor, IProgressMonitor) for detailed
	 *      comment
	 */
	public List searchSourceOnly(SearchPattern pattern,
			SearchParticipant[] participants, IDLTKSearchScope scope,
			IProgressMonitor monitor) throws CoreException {
		if (VERBOSE) {
			Util
					.verbose("BasicSearchEngine.search(SearchPattern, SearchParticipant[], IJavaSearchScope, SearchRequestor, IProgressMonitor)"); //$NON-NLS-1$
		}
		return findMatchesSourceOnly(pattern, participants, scope, monitor);
	}

	/**
	 * Searches for all secondary types in the given scope. The search can be
	 * selecting specific types (given a package or a type name prefix and match
	 * modes).
	 */
	public void searchAllSecondaryTypeNames(IProjectFragment[] sourceFolders,
			final IRestrictedAccessTypeRequestor nameRequestor,
			boolean waitForIndexes, IProgressMonitor progressMonitor)
			throws ModelException {
		//
		// if (VERBOSE) {
		// Util.verbose("BasicSearchEngine.searchAllSecondaryTypeNames(IProjectFragment[],
		// IRestrictedAccessTypeRequestor, boolean, IProgressMonitor)");
		// //$NON-NLS-1$
		// StringBuffer buffer = new StringBuffer(" - source folders: ");
		// //$NON-NLS-1$
		// int length = sourceFolders.length;
		// for (int i=0; i<length; i++) {
		// if (i==0) {
		// buffer.append('[');
		// } else {
		// buffer.append(',');
		// }
		// buffer.append(sourceFolders[i].getElementName());
		// }
		// buffer.append("]\n - waitForIndexes: "); //$NON-NLS-1$
		// buffer.append(waitForIndexes);
		// Util.verbose(buffer.toString());
		// }
		//
		// IndexManager indexManager =
		// ModelManager.getModelManager().getIndexManager();
		// final TypeDeclarationPattern pattern = new
		// SecondaryTypeDeclarationPattern();
		//
		// // Get working copy path(s). Store in a single string in case of only
		// one to optimize comparison in requestor
		// final HashSet workingCopyPaths = new HashSet();
		// String workingCopyPath = null;
		// ISourceModule[] copies = getWorkingCopies();
		// final int copiesLength = copies == null ? 0 : copies.length;
		// if (copies != null) {
		// if (copiesLength == 1) {
		// workingCopyPath = copies[0].getPath().toString();
		// } else {
		// for (int i = 0; i < copiesLength; i++) {
		// ISourceModule workingCopy = copies[i];
		// workingCopyPaths.add(workingCopy.getPath().toString());
		// }
		// }
		// }
		// final String singleWkcpPath = workingCopyPath;
		//
		// // Index requestor
		// IndexQueryRequestor searchRequestor = new IndexQueryRequestor(){
		// public boolean acceptIndexMatch(String documentPath, SearchPattern
		// indexRecord, SearchParticipant participant, AccessRuleSet access) {
		// // Filter unexpected types
		// TypeDeclarationPattern record = (TypeDeclarationPattern)indexRecord;
		// if (!record.secondary) {
		// return true; // filter maint types
		// }
		// if (record.enclosingTypeNames == IIndexConstants.ONE_ZERO_CHAR) {
		// return true; // filter out local and anonymous classes
		// }
		// switch (copiesLength) {
		// case 0:
		// break;
		// case 1:
		// if (singleWkcpPath.equals(documentPath)) {
		// return true; // fliter out *the* working copy
		// }
		// break;
		// default:
		// if (workingCopyPaths.contains(documentPath)) {
		// return true; // filter out working copies
		// }
		// break;
		// }
		//
		// // Accept document path
		// AccessRestriction accessRestriction = null;
		// if (access != null) {
		// // Compute document relative path
		// int pkgLength = (record.pkg==null || record.pkg.length==0) ? 0 :
		// record.pkg.length+1;
		// int nameLength = record.simpleName==null ? 0 :
		// record.simpleName.length;
		// char[] path = new char[pkgLength+nameLength];
		// int pos = 0;
		// if (pkgLength > 0) {
		// System.arraycopy(record.pkg, 0, path, pos, pkgLength-1);
		// CharOperation.replace(path, '.', '/');
		// path[pkgLength-1] = '/';
		// pos += pkgLength;
		// }
		// if (nameLength > 0) {
		// System.arraycopy(record.simpleName, 0, path, pos, nameLength);
		// pos += nameLength;
		// }
		// // Update access restriction if path is not empty
		// if (pos > 0) {
		// accessRestriction = access.getViolatedRestriction(path);
		// }
		// }
		// nameRequestor.acceptType(record.modifiers, record.pkg,
		// record.simpleName, record.enclosingTypeNames, documentPath,
		// accessRestriction);
		// return true;
		// }
		// };
		//
		// // add type names from indexes
		// if (progressMonitor != null) {
		// progressMonitor.beginTask(Messages.engine_searching, 100);
		// }
		// try {
		// indexManager.performConcurrentJob(
		// new PatternSearchJob(
		// pattern,
		// getDefaultSearchParticipant(), // Script search only
		// createJavaSearchScope(sourceFolders),
		// searchRequestor),
		// waitForIndexes
		// ? IDLTKSearchConstants.WAIT_UNTIL_READY_TO_SEARCH
		// : IDLTKSearchConstants.FORCE_IMMEDIATE_SEARCH,
		// progressMonitor == null ? null : new
		// SubProgressMonitor(progressMonitor, 100));
		// }
		// catch (OperationCanceledException oce) {
		// // do nothing
		// }
	}

	/**
	 * Searches for all top-level types and member types in the given scope. The
	 * search can be selecting specific types (given a package or a type name
	 * prefix and match modes).
	 *
	 * @see SearchEngine#searchAllTypeNames(char[], char[], int, int,
	 *      IJavaSearchScope, TypeNameRequestor, int, IProgressMonitor) for
	 *      detailed comment
	 */
	public void searchAllTypeNames(final char[] packageName,
			final int packageMatchRule, final char[] typeName,
			final int typeMatchRule, int searchFor, IDLTKSearchScope scope,
			final IRestrictedAccessTypeRequestor nameRequestor,
			int waitingPolicy, IProgressMonitor progressMonitor)
			throws ModelException {

		if (VERBOSE) {
			Util
					.verbose("BasicSearchEngine.searchAllTypeNames(char[], char[], int, int, IJavaSearchScope, IRestrictedAccessTypeRequestor, int, IProgressMonitor)"); //$NON-NLS-1$
			Util
					.verbose("	- package name: " + (packageName == null ? "null" : new String(packageName))); //$NON-NLS-1$ //$NON-NLS-2$
			Util
					.verbose("	- match rule: " + getMatchRuleString(packageMatchRule)); //$NON-NLS-1$
			Util
					.verbose("	- type name: " + (typeName == null ? "null" : new String(typeName))); //$NON-NLS-1$ //$NON-NLS-2$
			Util.verbose("	- match rule: " + getMatchRuleString(typeMatchRule)); //$NON-NLS-1$
			Util.verbose("	- search for: " + searchFor); //$NON-NLS-1$
			Util.verbose("	- scope: " + scope); //$NON-NLS-1$
		}

		// Return on invalid combination of package and type names
		if (packageName == null || packageName.length == 0) {
			if (typeName != null && typeName.length == 0) {
				// TODO (frederic) Throw a JME instead?
				if (VERBOSE) {
					Util
							.verbose("	=> return no result due to invalid empty values for package and type names!"); //$NON-NLS-1$
				}
				return;
			}
		}

		// Create pattern
		IndexManager indexManager = ModelManager.getModelManager()
				.getIndexManager();
		final char typeSuffix;
		switch (searchFor) {
		case IDLTKSearchConstants.TYPE:
			typeSuffix = IIndexConstants.TYPE_SUFFIX;
			break;
		case IDLTKSearchConstants.ANNOTATION_TYPE:
			typeSuffix = IIndexConstants.ANNOTATION_TYPE_SUFFIX;
			break;
		default:
			typeSuffix = IIndexConstants.TYPE_SUFFIX;
			break;
		}
		final TypeDeclarationPattern pattern = packageMatchRule == SearchPattern.R_EXACT_MATCH ? new TypeDeclarationPattern(
				packageName, null, typeName, typeSuffix, typeMatchRule)
				: new QualifiedTypeDeclarationPattern(packageName,
						packageMatchRule, typeName, typeSuffix, typeMatchRule);

		// Get working copy path(s). Store in a single string in case of only
		// one to optimize comparison in requestor
		final HashSet workingCopyPaths = new HashSet();
		String workingCopyPath = null;
		ISourceModule[] copies = getWorkingCopies();
		final int copiesLength = copies == null ? 0 : copies.length;
		if (copies != null) {
			if (copiesLength == 1) {
				workingCopyPath = copies[0].getPath().toString();
			} else {
				for (int i = 0; i < copiesLength; i++) {
					ISourceModule workingCopy = copies[i];
					workingCopyPaths.add(workingCopy.getPath().toString());
				}
			}
		}
		final String singleWkcpPath = workingCopyPath;
		// final List documentPathFilter = new ArrayList();
		// Index requestor
		IndexQueryRequestor searchRequestor = new IndexQueryRequestor() {
			public boolean acceptIndexMatch(String documentPath,
					SearchPattern indexRecord, SearchParticipant participant,
					AccessRuleSet access) {
				// IPath fullPath = new Path(documentPath);
				// if( documentPathFilter.contains(fullPath)) {
				// return true;
				// }
				// documentPathFilter.add(fullPath);
				// Filter unexpected types
				TypeDeclarationPattern record = (TypeDeclarationPattern) indexRecord;
				if (record.enclosingTypeNames == IIndexConstants.ONE_ZERO_CHAR) {
					return true; // filter out local and anonymous classes
				}
				switch (copiesLength) {
				case 0:
					break;
				case 1:
					if (singleWkcpPath.equals(documentPath)) {
						return true; // fliter out *the* working copy
					}
					break;
				default:
					if (workingCopyPaths.contains(documentPath)) {
						return true; // filter out working copies
					}
					break;
				}

				// Accept document path
				AccessRestriction accessRestriction = null;
				if (access != null) {
					// Compute document relative path
					int pkgLength = (record.pkg == null || record.pkg.length == 0) ? 0
							: record.pkg.length + 1;
					int nameLength = record.simpleName == null ? 0
							: record.simpleName.length;
					char[] path = new char[pkgLength + nameLength];
					int pos = 0;
					if (pkgLength > 0) {
						System.arraycopy(record.pkg, 0, path, pos,
								pkgLength - 1);
						CharOperation.replace(path, '.', '/');
						path[pkgLength - 1] = '/';
						pos += pkgLength;
					}
					if (nameLength > 0) {
						System.arraycopy(record.simpleName, 0, path, pos,
								nameLength);
						pos += nameLength;
					}
					// Update access restriction if path is not empty
					if (pos > 0) {
						accessRestriction = access.getViolatedRestriction(path);
					}
				}
				if (match(record.typeSuffix, record.modifiers)) {
					nameRequestor.acceptType(record.modifiers, record.pkg,
							record.simpleName, record.enclosingTypeNames,
							documentPath, accessRestriction);
				}
				return true;
			}
		};

		try {
			if (progressMonitor != null) {
				progressMonitor.beginTask(Messages.engine_searching, 100);
			}
			// add type names from indexes
			indexManager.performConcurrentJob(new PatternSearchJob(pattern,
					getDefaultSearchParticipant(), // Script search only
					scope, searchRequestor), waitingPolicy,
					progressMonitor == null ? null : new SubProgressMonitor(
							progressMonitor, 100));

			// add type names from working copies
			if (copies != null) {
				for (int i = 0; i < copiesLength; i++) {
					ISourceModule workingCopy = copies[i];
					if (!scope.encloses(workingCopy)) {
						continue;
					}
					final String path = workingCopy.getPath().toString();
					// if (workingCopy.isConsistent()) {
					// IPackageDeclaration[] packageDeclarations =
					// workingCopy.getPackageDeclarations();
					// char[] packageDeclaration = packageDeclarations.length ==
					// 0 ? CharOperation.NO_CHAR :
					// packageDeclarations[0].getElementName().toCharArray();
					IType[] allTypes = workingCopy.getTypes();
					for (int j = 0; j < allTypes.length; j++) {
						IType type = allTypes[i];
						IModelElement parent = type.getParent();
						char[][] enclosingTypeNames;
						if (parent instanceof IType) {
							char[] parentQualifiedName = ((IType) parent)
									.getTypeQualifiedName().toCharArray();
							enclosingTypeNames = CharOperation.splitOn('.',
									parentQualifiedName);
						} else {
							enclosingTypeNames = CharOperation.NO_CHAR_CHAR;
						}
						char[] simpleName = type.getElementName().toCharArray();
						int kind = 0;
						if (match(typeSuffix, packageName, typeName,
								typeMatchRule, kind, /* packageDeclaration, */
								simpleName)) {
							nameRequestor.acceptType(type.getFlags(),
									new char[0], /* packageDeclaration, */
									simpleName, enclosingTypeNames, path, null);
						}
					}
					// }
				}
			}
		} finally {
			if (progressMonitor != null) {
				progressMonitor.done();
			}
		}
	}

	/**
	 * Searches for all top-level types and member types in the given scope
	 * using a case sensitive exact match with the given qualified names and
	 * type names.
	 *
	 * @see SearchEngine#searchAllTypeNames(char[][], char[][],
	 *      IJavaSearchScope, TypeNameRequestor, int, IProgressMonitor) for
	 *      detailed comment
	 */
	public void searchAllTypeNames(final char[][] qualifications,
			final char[][] typeNames, final int matchRule, int searchFor,
			IDLTKSearchScope scope,
			final IRestrictedAccessTypeRequestor nameRequestor,
			int waitingPolicy, IProgressMonitor progressMonitor)
			throws ModelException {

		if (VERBOSE) {
			Util
					.verbose("BasicSearchEngine.searchAllTypeNames(char[][], char[][], int, int, IJavaSearchScope, IRestrictedAccessTypeRequestor, int, IProgressMonitor)"); //$NON-NLS-1$
			Util
					.verbose("	- package name: " + (qualifications == null ? "null" : new String(CharOperation.concatWith(qualifications, ',')))); //$NON-NLS-1$ //$NON-NLS-2$
			Util
					.verbose("	- type name: " + (typeNames == null ? "null" : new String(CharOperation.concatWith(typeNames, ',')))); //$NON-NLS-1$ //$NON-NLS-2$
			Util.verbose("	- match rule: " + matchRule); //$NON-NLS-1$
			Util.verbose("	- search for: " + searchFor); //$NON-NLS-1$
			Util.verbose("	- scope: " + scope); //$NON-NLS-1$
		}
		// IndexManager indexManager =
		// ModelManager.getModelManager().getIndexManager();
		//
		// final char typeSuffix;
		// switch(searchFor){
		// case IDLTKSearchConstants.CLASS :
		// typeSuffix = IIndexConstants.CLASS_SUFFIX;
		// break;
		// case IDLTKSearchConstants.CLASS_AND_INTERFACE :
		// typeSuffix = IIndexConstants.CLASS_AND_INTERFACE_SUFFIX;
		// break;
		// case IDLTKSearchConstants.CLASS_AND_ENUM :
		// typeSuffix = IIndexConstants.CLASS_AND_ENUM_SUFFIX;
		// break;
		// case IDLTKSearchConstants.INTERFACE :
		// typeSuffix = IIndexConstants.INTERFACE_SUFFIX;
		// break;
		// case IDLTKSearchConstants.ENUM :
		// typeSuffix = IIndexConstants.ENUM_SUFFIX;
		// break;
		// case IDLTKSearchConstants.ANNOTATION_TYPE :
		// typeSuffix = IIndexConstants.ANNOTATION_TYPE_SUFFIX;
		// break;
		// default :
		// typeSuffix = IIndexConstants.TYPE_SUFFIX;
		// break;
		// }
		// final MultiTypeDeclarationPattern pattern = new
		// MultiTypeDeclarationPattern(qualifications, typeNames, typeSuffix,
		// matchRule);
		//
		// // Get working copy path(s). Store in a single string in case of only
		// one to optimize comparison in requestor
		// final HashSet workingCopyPaths = new HashSet();
		// String workingCopyPath = null;
		// ISourceModule[] copies = getWorkingCopies();
		// final int copiesLength = copies == null ? 0 : copies.length;
		// if (copies != null) {
		// if (copiesLength == 1) {
		// workingCopyPath = copies[0].getPath().toString();
		// } else {
		// for (int i = 0; i < copiesLength; i++) {
		// ISourceModule workingCopy = copies[i];
		// workingCopyPaths.add(workingCopy.getPath().toString());
		// }
		// }
		// }
		// final String singleWkcpPath = workingCopyPath;
		//
		// // Index requestor
		// IndexQueryRequestor searchRequestor = new IndexQueryRequestor(){
		// public boolean acceptIndexMatch(String documentPath, SearchPattern
		// indexRecord, SearchParticipant participant, AccessRuleSet access) {
		// // Filter unexpected types
		// switch (copiesLength) {
		// case 0:
		// break;
		// case 1:
		// if (singleWkcpPath.equals(documentPath)) {
		// return true; // fliter out *the* working copy
		// }
		// break;
		// default:
		// if (workingCopyPaths.contains(documentPath)) {
		// return true; // filter out working copies
		// }
		// break;
		// }
		//
		// // Accept document path
		// QualifiedTypeDeclarationPattern record =
		// (QualifiedTypeDeclarationPattern) indexRecord;
		// AccessRestriction accessRestriction = null;
		// if (access != null) {
		// // Compute document relative path
		// int qualificationLength = (record.qualification == null ||
		// record.qualification.length == 0) ? 0 : record.qualification.length +
		// 1;
		// int nameLength = record.simpleName == null ? 0 :
		// record.simpleName.length;
		// char[] path = new char[qualificationLength + nameLength];
		// int pos = 0;
		// if (qualificationLength > 0) {
		// System.arraycopy(record.qualification, 0, path, pos,
		// qualificationLength - 1);
		// CharOperation.replace(path, '.', '/');
		// path[qualificationLength-1] = '/';
		// pos += qualificationLength;
		// }
		// if (nameLength > 0) {
		// System.arraycopy(record.simpleName, 0, path, pos, nameLength);
		// pos += nameLength;
		// }
		// // Update access restriction if path is not empty
		// if (pos > 0) {
		// accessRestriction = access.getViolatedRestriction(path);
		// }
		// }
		// nameRequestor.acceptType(record.modifiers, record.pkg,
		// record.simpleName, record.enclosingTypeNames, documentPath,
		// accessRestriction);
		// return true;
		// }
		// };
		//
		// try {
		// if (progressMonitor != null) {
		// progressMonitor.beginTask(Messages.engine_searching, 100);
		// }
		// // add type names from indexes
		// indexManager.performConcurrentJob(
		// new PatternSearchJob(
		// pattern,
		// getDefaultSearchParticipant(), // Script search only
		// scope,
		// searchRequestor),
		// waitingPolicy,
		// progressMonitor == null ? null : new
		// SubProgressMonitor(progressMonitor, 100));
		//
		// // add type names from working copies
		// if (copies != null) {
		// for (int i = 0, length = copies.length; i < length; i++) {
		// ISourceModule workingCopy = copies[i];
		// final String path = workingCopy.getPath().toString();
		// if (workingCopy.isConsistent()) {
		// IPackageDeclaration[] packageDeclarations =
		// workingCopy.getPackageDeclarations();
		// char[] packageDeclaration = packageDeclarations.length == 0 ?
		// CharOperation.NO_CHAR :
		// packageDeclarations[0].getElementName().toCharArray();
		// IType[] allTypes = workingCopy.getAllTypes();
		// for (int j = 0, allTypesLength = allTypes.length; j < allTypesLength;
		// j++) {
		// IType type = allTypes[j];
		// IModelElement parent = type.getParent();
		// char[][] enclosingTypeNames;
		// char[] qualification = packageDeclaration;
		// if (parent instanceof IType) {
		// char[] parentQualifiedName =
		// ((IType)parent).getTypeQualifiedName('.').toCharArray();
		// enclosingTypeNames = CharOperation.splitOn('.', parentQualifiedName);
		// qualification = CharOperation.concat(qualification,
		// parentQualifiedName);
		// } else {
		// enclosingTypeNames = CharOperation.NO_CHAR_CHAR;
		// }
		// char[] simpleName = type.getElementName().toCharArray();
		// char suffix = IIndexConstants.TYPE_SUFFIX;
		// if (type.isClass()) {
		// suffix = IIndexConstants.CLASS_SUFFIX;
		// } else if (type.isInterface()) {
		// suffix = IIndexConstants.INTERFACE_SUFFIX;
		// } else if (type.isEnum()) {
		// suffix = IIndexConstants.ENUM_SUFFIX;
		// } else if (type.isAnnotation()) {
		// suffix = IIndexConstants.ANNOTATION_TYPE_SUFFIX;
		// }
		// if (pattern.matchesDecodedKey(new
		// QualifiedTypeDeclarationPattern(qualification, simpleName, suffix,
		// matchRule))) {
		// nameRequestor.acceptType(type.getFlags(), packageDeclaration,
		// simpleName, enclosingTypeNames, path, null);
		// }
		// }
		// } else {
		// Parser basicParser = getParser();
		// org.eclipse.dltk.internal.compiler.env.ISourceModule unit =
		// (org.eclipse.dltk.internal.compiler.env.ISourceModule) workingCopy;
		// CompilationResult compilationUnitResult = new CompilationResult(unit,
		// 0, 0, this.compilerOptions.maxProblemsPerUnit);
		// SourceModuleDeclaration parsedUnit = basicParser.dietParse(unit,
		// compilationUnitResult);
		// if (parsedUnit != null) {
		// final char[] packageDeclaration = parsedUnit.currentPackage == null
		// ? CharOperation.NO_CHAR
		// : CharOperation.concatWith(parsedUnit.currentPackage.getImportName(),
		// '.');
		// class AllTypeDeclarationsVisitor extends ASTVisitor {
		// public boolean visit(TypeDeclaration typeDeclaration, BlockScope
		// blockScope) {
		// return false; // no local/anonymous type
		// }
		// public boolean visit(TypeDeclaration typeDeclaration,
		// SourceModuleScope compilationUnitScope) {
		// SearchPattern decodedPattern =
		// new QualifiedTypeDeclarationPattern(packageDeclaration,
		// typeDeclaration.name,
		// convertTypeKind(TypeDeclaration.kind(typeDeclaration.modifiers)),
		// matchRule);
		// if (pattern.matchesDecodedKey(decodedPattern)) {
		// nameRequestor.acceptType(typeDeclaration.modifiers,
		// packageDeclaration, typeDeclaration.name, CharOperation.NO_CHAR_CHAR,
		// path, null);
		// Parser basicParser = getParser();
		// org.eclipse.dltk.internal.compiler.env.ISourceModule unit =
		// (org.eclipse.dltk.internal.compiler.env.ISourceModule) workingCopy;
		// CompilationResult compilationUnitResult = new CompilationResult(unit,
		// 0, 0, this.compilerOptions.maxProblemsPerUnit);
		// SourceModuleDeclaration parsedUnit = basicParser.dietParse(unit,
		// compilationUnitResult);
		// if (parsedUnit != null) {
		// final char[] packageDeclaration = parsedUnit.currentPackage == null
		// ? CharOperation.NO_CHAR
		// : CharOperation.concatWith(parsedUnit.currentPackage.getImportName(),
		// '.');
		// class AllTypeDeclarationsVisitor extends ASTVisitor {
		// public boolean visit(TypeDeclaration typeDeclaration, BlockScope
		// blockScope) {
		// return false; // no local/anonymous type
		// }
		// public boolean visit(TypeDeclaration typeDeclaration,
		// SourceModuleScope compilationUnitScope) {
		// SearchPattern decodedPattern =
		// new QualifiedTypeDeclarationPattern(packageDeclaration,
		// typeDeclaration.name,
		// convertTypeKind(TypeDeclaration.kind(typeDeclaration.modifiers)),
		// matchRule);
		// if (pattern.matchesDecodedKey(decodedPattern)) {
		// nameRequestor.acceptType(typeDeclaration.modifiers,
		// packageDeclaration, typeDeclaration.name, CharOperation.NO_CHAR_CHAR,
		// path, null);
		// }
		// return true;
		// }
		// public boolean visit(TypeDeclaration memberTypeDeclaration,
		// ClassScope classScope) {
		// // compute encloising type names
		// char[] qualification = packageDeclaration;
		// TypeDeclaration enclosing = memberTypeDeclaration.enclosingType;
		// char[][] enclosingTypeNames = CharOperation.NO_CHAR_CHAR;
		// while (enclosing != null) {
		// qualification = CharOperation.concat(qualification, enclosing.name,
		// '.');
		// enclosingTypeNames = CharOperation.arrayConcat(new char[][]
		// {enclosing.name}, enclosingTypeNames);
		// if ((enclosing.bits & ASTNode.IsMemberType) != 0) {
		// enclosing = enclosing.enclosingType;
		// } else {
		// enclosing = null;
		// }
		// }
		// SearchPattern decodedPattern =
		// new QualifiedTypeDeclarationPattern(qualification,
		// memberTypeDeclaration.name,
		// convertTypeKind(TypeDeclaration.kind(memberTypeDeclaration.modifiers)),
		// matchRule);
		// if (pattern.matchesDecodedKey(decodedPattern)) {
		// nameRequestor.acceptType(memberTypeDeclaration.modifiers,
		// packageDeclaration, memberTypeDeclaration.name, enclosingTypeNames,
		// path, null);
		// }
		// return true;
		// }
		// }
		// parsedUnit.traverse(new AllTypeDeclarationsVisitor(),
		// parsedUnit.scope);}
		// return true;
		// }
		// public boolean visit(TypeDeclaration memberTypeDeclaration,
		// ClassScope classScope) {
		// // compute encloising type names
		// char[] qualification = packageDeclaration;
		// TypeDeclaration enclosing = memberTypeDeclaration.enclosingType;
		// char[][] enclosingTypeNames = CharOperation.NO_CHAR_CHAR;
		// while (enclosing != null) {
		// qualification = CharOperation.concat(qualification, enclosing.name,
		// '.');
		// enclosingTypeNames = CharOperation.arrayConcat(new char[][]
		// {enclosing.name}, enclosingTypeNames);
		// if ((enclosing.bits & ASTNode.IsMemberType) != 0) {
		// enclosing = enclosing.enclosingType;
		// } else {
		// enclosing = null;
		// }
		// }
		// SearchPattern decodedPattern =
		// new QualifiedTypeDeclarationPattern(qualification,
		// memberTypeDeclaration.name,
		// convertTypeKind(TypeDeclaration.kind(memberTypeDeclaration.modifiers)),
		// matchRule);
		// if (pattern.matchesDecodedKey(decodedPattern)) {
		// nameRequestor.acceptType(memberTypeDeclaration.modifiers,
		// packageDeclaration, memberTypeDeclaration.name, enclosingTypeNames,
		// path, null);
		// }
		// return true;
		// }
		// }
		// parsedUnit.traverse(new AllTypeDeclarationsVisitor(),
		// parsedUnit.scope);
		// }
		// }
		// }
		// }
		// } finally {
		// if (progressMonitor != null) {
		// progressMonitor.done();
		// }
		// }
	}

	public DLTKSearchParticipant getSearchParticipant(IModelElement element) {
		IDLTKLanguageToolkit toolkit = null;
		try {
			toolkit = DLTKLanguageManager.getLanguageToolkit(element);
		} catch (CoreException e) {
			e.printStackTrace();
		}
		if (toolkit != null) {
			DLTKSearchParticipant par = DLTKLanguageManager
					.createSearchParticipant(toolkit.getNatureId());
			if (par != null) {
				return par;
			}
		}
		return new DLTKSearchParticipant();
	}

	public void searchDeclarations(IModelElement enclosingElement,
			SearchRequestor requestor, SearchPattern pattern,
			IProgressMonitor monitor) throws ModelException {
		if (VERBOSE) {
			Util.verbose("	- script element: " + enclosingElement); //$NON-NLS-1$
		}
		IDLTKSearchScope scope = createSearchScope(new IModelElement[] { enclosingElement });
		IResource resource = enclosingElement.getResource();
		if (enclosingElement instanceof IMember) {
			IMember member = (IMember) enclosingElement;
			ISourceModule cu = member.getSourceModule();
			if (cu != null) {
				resource = cu.getResource();
			} else if (((IProjectFragment) member
					.getAncestor(IModelElement.PROJECT_FRAGMENT)).isExternal()) {
				// binary member resource cannot be used as this
				// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=148215
				resource = null;
			}
		}
		try {
			if (resource instanceof IFile) {
				try {
					requestor.beginReporting();
					if (VERBOSE) {
						Util
								.verbose("Searching for " + pattern + " in " + resource.getFullPath()); //$NON-NLS-1$//$NON-NLS-2$
					}
					SearchParticipant participant = getSearchParticipant(enclosingElement);
					boolean external = false;
					IProjectFragment fragment = (IProjectFragment) enclosingElement
							.getAncestor(IModelElement.PROJECT_FRAGMENT);
					if (fragment != null) {
						external = fragment.isExternal();
					}
					SearchDocument[] documents = MatchLocator.addWorkingCopies(
							pattern,
							new SearchDocument[] { new DLTKSearchDocument(
									enclosingElement.getPath().toString(),
									participant, external) },
							getWorkingCopies(enclosingElement), participant);
					participant.locateMatches(documents, pattern, scope,
							requestor, monitor);
				} finally {
					requestor.endReporting();
				}
			} else {
				search(
						pattern,
						new SearchParticipant[] { getDefaultSearchParticipant() },
						scope, requestor, monitor);
			}
		} catch (CoreException e) {
			if (e instanceof ModelException) {
				throw (ModelException) e;
			}
			throw new ModelException(e);
		}
	}

	/**
	 * Searches for all declarations of the fields accessed in the given
	 * element. The element can be a compilation unit, a source type, or a
	 * source method. Reports the field declarations using the given requestor.
	 *
	 * @see SearchEngine#searchDeclarationsOfAccessedFields(IModelElement,
	 *      SearchRequestor, IProgressMonitor) for detailed comment
	 */
	public void searchDeclarationsOfAccessedFields(
			IModelElement enclosingElement, SearchRequestor requestor,
			IProgressMonitor monitor) throws ModelException {
		// if (VERBOSE) {
		// Util.verbose("BasicSearchEngine.searchDeclarationsOfAccessedFields(IModelElement,
		// SearchRequestor, SearchPattern, IProgressMonitor)"); //$NON-NLS-1$
		// }
		// SearchPattern pattern = new
		// DeclarationOfAccessedFieldsPattern(enclosingElement);
		// searchDeclarations(enclosingElement, requestor, pattern, monitor);
	}

	/**
	 * Searches for all declarations of the types referenced in the given
	 * element. The element can be a compilation unit, a source type, or a
	 * source method. Reports the type declarations using the given requestor.
	 *
	 * @see SearchEngine#searchDeclarationsOfReferencedTypes(IModelElement,
	 *      SearchRequestor, IProgressMonitor) for detailed comment
	 */
	public void searchDeclarationsOfReferencedTypes(
			IModelElement enclosingElement, SearchRequestor requestor,
			IProgressMonitor monitor) throws ModelException {
		// if (VERBOSE) {
		// Util.verbose("BasicSearchEngine.searchDeclarationsOfReferencedTypes(IModelElement,
		// SearchRequestor, SearchPattern, IProgressMonitor)"); //$NON-NLS-1$
		// }
		// SearchPattern pattern = new
		// DeclarationOfReferencedTypesPattern(enclosingElement);
		// searchDeclarations(enclosingElement, requestor, pattern, monitor);
	}

	/**
	 * Searches for all declarations of the methods invoked in the given
	 * element. The element can be a compilation unit, a source type, or a
	 * source method. Reports the method declarations using the given requestor.
	 *
	 * @see SearchEngine#searchDeclarationsOfSentMessages(IModelElement,
	 *      SearchRequestor, IProgressMonitor) for detailed comment
	 */
	public void searchDeclarationsOfSentMessages(
			IModelElement enclosingElement, SearchRequestor requestor,
			IProgressMonitor monitor) throws ModelException {
		// if (VERBOSE) {
		// Util.verbose("BasicSearchEngine.searchDeclarationsOfSentMessages(IModelElement,
		// SearchRequestor, SearchPattern, IProgressMonitor)"); //$NON-NLS-1$
		// }
		// SearchPattern pattern = new
		// DeclarationOfReferencedMethodsPattern(enclosingElement);
		// searchDeclarations(enclosingElement, requestor, pattern, monitor);
	}
}
