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

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.SubProgressMonitor;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;

import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.RefactoringStatusEntry;

import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.WorkingCopyOwner;
import org.eclipse.jdt.core.search.IJavaSearchScope;
import org.eclipse.jdt.core.search.SearchEngine;
import org.eclipse.jdt.core.search.SearchMatch;
import org.eclipse.jdt.core.search.SearchPattern;
import org.eclipse.jdt.core.search.SearchRequestor;

import org.eclipse.jdt.internal.corext.util.Messages;
import org.eclipse.jdt.internal.corext.util.SearchUtils;

import org.eclipse.jdt.internal.ui.viewsupport.BasicElementLabels;

/**
 * Helper class to use the search engine in refactorings.
 *
 * TODO:
 * - is inefficient: uses sets instead of lists, creates useless intermediate collections
 * - destroys locality by doing multiple passes over result sets instead of processing results in a pipeline
 * - does not allow users to modify search matches
 * - generates boilerplate error messages and has no way to configure them
 *
 * @since 3.1
 */
public final class RefactoringSearchEngine2 {

	/** Default implementation of a search requestor */
	private static class DefaultSearchRequestor implements IRefactoringSearchRequestor {

		@Override
		public final SearchMatch acceptSearchMatch(final SearchMatch match) {
			return match;
		}
	}

	/** Search requestor which only collects compilation units */
	private class RefactoringCompilationUnitCollector extends RefactoringSearchCollector {

		/** The collected compilation units */
		private final Set<ICompilationUnit> fCollectedUnits= new HashSet<>();

		/** The inaccurate matches */
		private final Set<SearchMatch> fInaccurateMatches= new HashSet<>();

		@Override
		public final void acceptSearchMatch(final SearchMatch match) throws CoreException {
			final SearchMatch accepted= fRequestor.acceptSearchMatch(match);
			if (accepted != null) {
				final IResource resource= accepted.getResource();
				if (!resource.equals(fLastResource)) {
					final IJavaElement element= JavaCore.create(resource);
					if (element instanceof ICompilationUnit)
						fCollectedUnits.add((ICompilationUnit) element);
				}
				if (fInaccurate && accepted.getAccuracy() == SearchMatch.A_INACCURATE && !fInaccurateMatches.contains(accepted)) {
					fStatus.addEntry(fSeverity, Messages.format(RefactoringCoreMessages.RefactoringSearchEngine_inaccurate_match, BasicElementLabels.getResourceName(accepted.getResource())), null, null, RefactoringStatusEntry.NO_CODE);
					fInaccurateMatches.add(accepted);
				}
			}
		}

		@Override
		public final void clearResults() {
			super.clearResults();
			fCollectedUnits.clear();
			fInaccurateMatches.clear();
		}

		@Override
		public final Collection<IResource> getBinaryResources() {
			return Collections.emptySet();
		}

		@Override
		public final Collection<ICompilationUnit> getCollectedMatches() {
			return fCollectedUnits;
		}

		@Override
		public final Collection<SearchMatch> getInaccurateMatches() {
			return fInaccurateMatches;
		}
	}

	private abstract class RefactoringSearchCollector extends SearchRequestor {

		protected IResource fLastResource= null;

		public void clearResults() {
			fLastResource= null;
		}

		public abstract Collection<IResource> getBinaryResources();

		public abstract Collection<?> getCollectedMatches();

		public abstract Collection<SearchMatch> getInaccurateMatches();
	}

	/** Search requestor which collects every search match */
	private class RefactoringSearchMatchCollector extends RefactoringSearchCollector {

		/** The binary resources */
		private final Set<IResource> fBinaryResources= new HashSet<>();

		/** The collected matches */
		private final List<SearchMatch> fCollectedMatches= new ArrayList<>();

		/** The inaccurate matches */
		private final Set<SearchMatch> fInaccurateMatches= new HashSet<>();

		@Override
		public final void acceptSearchMatch(final SearchMatch match) throws CoreException {
			final SearchMatch accepted= fRequestor.acceptSearchMatch(match);
			if (accepted != null) {
				fCollectedMatches.add(accepted);
				final IResource resource= accepted.getResource();
				if (!resource.equals(fLastResource)) {
					if (fBinary) {
						final IJavaElement element= JavaCore.create(resource);
						if (!(element instanceof ICompilationUnit)) {
							final IProject project= resource.getProject();
							if (!fGrouping)
								fStatus.addEntry(fSeverity, Messages.format(RefactoringCoreMessages.RefactoringSearchEngine_binary_match_ungrouped, BasicElementLabels.getResourceName(project)), null, null, RefactoringStatusEntry.NO_CODE);
							else if (!fBinaryResources.contains(resource))
								fStatus.addEntry(fSeverity, Messages.format(RefactoringCoreMessages.RefactoringSearchEngine_binary_match_grouped, BasicElementLabels.getResourceName(project)), null, null, RefactoringStatusEntry.NO_CODE);
							fBinaryResources.add(resource);
						}
					}
					if (fInaccurate && accepted.getAccuracy() == SearchMatch.A_INACCURATE && !fInaccurateMatches.contains(accepted)) {
						fStatus.addEntry(fSeverity, Messages.format(RefactoringCoreMessages.RefactoringSearchEngine_inaccurate_match, BasicElementLabels.getResourceName(resource)), null, null, RefactoringStatusEntry.NO_CODE);
						fInaccurateMatches.add(accepted);
					}
				}
			}
		}

		@Override
		public final void clearResults() {
			super.clearResults();
			fCollectedMatches.clear();
			fInaccurateMatches.clear();
			fBinaryResources.clear();
		}

		@Override
		public final Collection<IResource> getBinaryResources() {
			return fBinaryResources;
		}

		@Override
		public final Collection<SearchMatch> getCollectedMatches() {
			return fCollectedMatches;
		}

		@Override
		public final Collection<SearchMatch> getInaccurateMatches() {
			return fInaccurateMatches;
		}
	}

	/** The compilation unit granularity */
	public static final int GRANULARITY_COMPILATION_UNIT= 2;

	/** The search match granularity */
	public static final int GRANULARITY_SEARCH_MATCH= 1;

	/** Should binary matches be filtered? */
	private boolean fBinary= false;

	/** The refactoring search collector */
	private RefactoringSearchCollector fCollector= null;

	/** The search granularity */
	private int fGranularity= GRANULARITY_SEARCH_MATCH;

	/** Should the matches be grouped by resource? */
	private boolean fGrouping= true;

	/** Should inaccurate matches be filtered? */
	private boolean fInaccurate= true;

	/** The working copy owner, or <code>null</code> */
	private WorkingCopyOwner fOwner= null;

	/** The search pattern, or <code>null</code> */
	private SearchPattern fPattern= null;

	/** The search requestor */
	private IRefactoringSearchRequestor fRequestor= new DefaultSearchRequestor();

	/** The search scope */
	private IJavaSearchScope fScope= SearchEngine.createWorkspaceScope();

	/** The severity */
	private int fSeverity= RefactoringStatus.WARNING;

	/** The search status */
	private RefactoringStatus fStatus= new RefactoringStatus();

	/** The working copies */
	private ICompilationUnit[] fWorkingCopies= {};

	/**
	 * Creates a new refactoring search engine.
	 */
	public RefactoringSearchEngine2() {
		// Do nothing
	}

	/**
	 * Creates a new refactoring search engine.
	 *
	 * @param pattern the search pattern
	 */
	public RefactoringSearchEngine2(final SearchPattern pattern) {
		Assert.isNotNull(pattern);
		fPattern= pattern;
	}

	/**
	 * Clears all results found so far, and sets resets the status to {@link RefactoringStatus#OK}.
	 */
	public final void clearResults() {
		getCollector().clearResults();
		fStatus= new RefactoringStatus();
	}

	/**
	 * Returns the affected compilation units of the previous search queries.
	 * <p>
	 * In order to retrieve the compilation units, grouping by resource must have been enabled before searching.
	 *
	 * @return the compilation units of the previous queries
	 */
	public final ICompilationUnit[] getAffectedCompilationUnits() {
		if (fGranularity == GRANULARITY_COMPILATION_UNIT) {
			final Collection<?> collection= getCollector().getCollectedMatches();
			final ICompilationUnit[] units= new ICompilationUnit[collection.size()];
			int index= 0;
			for (final Iterator<?> iterator= collection.iterator(); iterator.hasNext(); index++)
				units[index]= (ICompilationUnit) iterator.next();
			return units;
		} else {
			final SearchResultGroup[] groups= getGroupedMatches();
			final ICompilationUnit[] units= new ICompilationUnit[groups.length];
			for (int index= 0; index < groups.length; index++)
				units[index]= groups[index].getCompilationUnit();
			return units;
		}
	}

	/**
	 * Returns the affected java projects of the previous search queries.
	 * <p>
	 * In order to retrieve the java projects, grouping by resource must have been enabled before searching.
	 *
	 * @return the java projects of the previous queries (element type:
	 * <code>&lt;IJavaProject, Collection&lt;SearchResultGroup&gt;&gt;</code> if granularity is {@link #GRANULARITY_SEARCH_MATCH} or
	 * <code>&lt;IJavaProject, Collection&lt;ICompilationUnit&gt;&gt;</code> if it is {@link #GRANULARITY_COMPILATION_UNIT}).
	 */
	public final Map<IJavaProject, ? extends Set<?>> getAffectedProjects() {
		IJavaProject project= null;
		ICompilationUnit unit= null;
		if (fGranularity == GRANULARITY_COMPILATION_UNIT) {
			final Map<IJavaProject, Set<ICompilationUnit>> map= new HashMap<>();
			final ICompilationUnit[] units= getAffectedCompilationUnits();
			for (int index= 0; index < units.length; index++) {
				unit= units[index];
				project= unit.getJavaProject();
				if (project != null) {
					Set<ICompilationUnit> set= map.get(project);
					if (set == null) {
						set= new HashSet<>();
						map.put(project, set);
					}
					set.add(unit);
				}
			}
			return map;
		} else {
			final Map<IJavaProject, Set<SearchResultGroup>> map= new HashMap<>();
			final SearchResultGroup[] groups= getGroupedMatches();
			SearchResultGroup group= null;
			for (int index= 0; index < groups.length; index++) {
				group= groups[index];
				unit= group.getCompilationUnit();
				if (unit != null) {
					project= unit.getJavaProject();
					if (project != null) {
						Set<SearchResultGroup> set= map.get(project);
						if (set == null) {
							set= new HashSet<>();
							map.put(project, set);
						}
						set.add(group);
					}
				}
			}
			return map;
		}
	}

	/**
	 * Returns the refactoring search collector.
	 *
	 * @return the refactoring search collector
	 */
	private RefactoringSearchCollector getCollector() {
		if (fCollector == null) {
			if (fGranularity == GRANULARITY_COMPILATION_UNIT)
				fCollector= new RefactoringCompilationUnitCollector();
			else if (fGranularity == GRANULARITY_SEARCH_MATCH)
				fCollector= new RefactoringSearchMatchCollector();
			else
				Assert.isTrue(false);
		}
		return fCollector;
	}

	/**
	 * Returns the found search matches in grouped by their containing resource.
	 *
	 * @return the found search matches
	 */
	private SearchResultGroup[] getGroupedMatches() {
		final Map<IResource, List<SearchMatch>> grouped= new HashMap<>();
		List<SearchMatch> matches= null;
		IResource resource= null;
		SearchMatch match= null;
		for (final Iterator<?> iterator= getSearchMatches().iterator(); iterator.hasNext();) {
			match= (SearchMatch) iterator.next();
			resource= match.getResource();
			if (!grouped.containsKey(resource))
				grouped.put(resource, new ArrayList<SearchMatch>(4));
			matches= grouped.get(resource);
			matches.add(match);
		}
		if (fBinary) {
			final Collection<IResource> collection= getCollector().getBinaryResources();
			for (final Iterator<IResource> iterator= grouped.keySet().iterator(); iterator.hasNext();) {
				resource= iterator.next();
				if (collection.contains(resource))
					iterator.remove();
			}
		}
		final SearchResultGroup[] result= new SearchResultGroup[grouped.keySet().size()];
		int index= 0;
		for (final Iterator<IResource> iterator= grouped.keySet().iterator(); iterator.hasNext();) {
			resource= iterator.next();
			matches= grouped.get(resource);
			result[index++]= new SearchResultGroup(resource, matches.toArray(new SearchMatch[matches.size()]));
		}
		return result;
	}

	/**
	 * Returns the search pattern currently used for searching.
	 *
	 * @return the search pattern
	 */
	public final SearchPattern getPattern() {
		return fPattern;
	}

	/**
	 * Returns the results of the previous search queries.
	 * <p>
	 * The result depends on the following conditions:
	 * <ul>
	 * <li>If the search granularity is {@link #GRANULARITY_COMPILATION_UNIT}, the results are elements of type {@link ICompilationUnit}.</li>
	 * <li>If grouping by resource is enabled, the results are elements of type {@link SearchResultGroup}, otherwise the elements are of type {@link SearchMatch}.</li>
	 * </ul>
	 *
	 * @return the results of the previous queries
	 */
	public final Object[] getResults() {
		if (fGranularity == GRANULARITY_COMPILATION_UNIT)
			return getAffectedCompilationUnits();
		else {
			if (fGrouping)
				return getGroupedMatches();
			else
				return getUngroupedMatches();
		}
	}

	/**
	 * Returns the search matches filtered by their accuracy.
	 *
	 * @return the filtered search matches
	 */
	private Collection<?> getSearchMatches() {
		Collection<?> results= null;
		if (fInaccurate) {
			results= new LinkedList<>(getCollector().getCollectedMatches());
			final Collection<SearchMatch> collection= getCollector().getInaccurateMatches();
			SearchMatch match= null;
			for (final Iterator<?> iterator= results.iterator(); iterator.hasNext();) {
				match= (SearchMatch) iterator.next();
				if (collection.contains(match))
					iterator.remove();
			}
		} else
			results= getCollector().getCollectedMatches();
		return results;
	}

	/**
	 * Returns the refactoring status of this search engine.
	 *
	 * @return the refactoring status
	 */
	public final RefactoringStatus getStatus() {
		return fStatus;
	}

	/**
	 * Returns the found search matches in no particular order.
	 *
	 * @return the found search matches
	 */
	private SearchMatch[] getUngroupedMatches() {
		Collection<?> results= null;
		if (fBinary) {
			results= new LinkedList<>(getSearchMatches());
			final Collection<IResource> collection= getCollector().getBinaryResources();
			SearchMatch match= null;
			for (final Iterator<?> iterator= results.iterator(); iterator.hasNext();) {
				match= (SearchMatch) iterator.next();
				if (collection.contains(match.getResource()))
					iterator.remove();
			}
		} else
			results= getSearchMatches();
		final SearchMatch[] matches= new SearchMatch[results.size()];
		results.toArray(matches);
		return matches;
	}

	/**
	 * Performs the search according to the specified pattern.
	 *
	 * @param monitor the progress monitor, or <code>null</code>
	 * @throws JavaModelException if an error occurs during search
	 */
	public final void searchPattern(IProgressMonitor monitor) throws JavaModelException {
		Assert.isNotNull(fPattern);
		if (monitor == null)
			monitor=  new NullProgressMonitor();
		try {
			monitor.beginTask("", 1); //$NON-NLS-1$
			monitor.setTaskName(RefactoringCoreMessages.RefactoringSearchEngine_searching_occurrences);
			try {
				SearchEngine engine= null;
				if (fOwner != null)
					engine= new SearchEngine(fOwner);
				else
					engine= new SearchEngine(fWorkingCopies);
				engine.search(fPattern, SearchUtils.getDefaultSearchParticipants(), fScope, getCollector(), new SubProgressMonitor(monitor, 1, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL));
			} catch (CoreException exception) {
				throw new JavaModelException(exception);
			}
		} finally {
			monitor.done();
		}
	}

	/**
	 * Performs the search of referenced fields.
	 *
	 * @param element the java element whose referenced fields have to be found
	 * @param monitor the progress monitor, or <code>null</code>
	 * @throws JavaModelException if an error occurs during search
	 */
	public final void searchReferencedFields(final IJavaElement element, IProgressMonitor monitor) throws JavaModelException {
		Assert.isNotNull(element);
		if (monitor == null)
			monitor=  new NullProgressMonitor();
		try {
			monitor.beginTask("", 1); //$NON-NLS-1$
			monitor.setTaskName(RefactoringCoreMessages.RefactoringSearchEngine_searching_referenced_fields);
			try {
				SearchEngine engine= null;
				if (fOwner != null)
					engine= new SearchEngine(fOwner);
				else
					engine= new SearchEngine(fWorkingCopies);
				engine.searchDeclarationsOfAccessedFields(element, getCollector(), new SubProgressMonitor(monitor, 1, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL));
			} catch (CoreException exception) {
				throw new JavaModelException(exception);
			}
		} finally {
			monitor.done();
		}
	}

	/**
	 * Performs the search of referenced methods.
	 *
	 * @param element the java element whose referenced methods have to be found
	 * @param monitor the progress monitor, or <code>null</code>
	 * @throws JavaModelException if an error occurs during search
	 */
	public final void searchReferencedMethods(final IJavaElement element, IProgressMonitor monitor) throws JavaModelException {
		Assert.isNotNull(element);
		if (monitor == null)
			monitor=  new NullProgressMonitor();
		try {
			monitor.beginTask("", 1); //$NON-NLS-1$
			monitor.setTaskName(RefactoringCoreMessages.RefactoringSearchEngine_searching_referenced_methods);
			try {
				SearchEngine engine= null;
				if (fOwner != null)
					engine= new SearchEngine(fOwner);
				else
					engine= new SearchEngine(fWorkingCopies);
				engine.searchDeclarationsOfSentMessages(element, getCollector(), new SubProgressMonitor(monitor, 1, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL));
			} catch (CoreException exception) {
				throw new JavaModelException(exception);
			}
		} finally {
			monitor.done();
		}
	}

	/**
	 * Performs the search of referenced types.
	 *
	 * @param element the java element whose referenced types have to be found
	 * @param monitor the progress monitor, or <code>null</code>
	 * @throws JavaModelException if an error occurs during search
	 */
	public final void searchReferencedTypes(final IJavaElement element, IProgressMonitor monitor) throws JavaModelException {
		Assert.isNotNull(element);
		if (monitor == null)
			monitor=  new NullProgressMonitor();
		try {
			monitor.beginTask("", 1); //$NON-NLS-1$
			monitor.setTaskName(RefactoringCoreMessages.RefactoringSearchEngine_searching_referenced_types);
			try {
				SearchEngine engine= null;
				if (fOwner != null)
					engine= new SearchEngine(fOwner);
				else
					engine= new SearchEngine(fWorkingCopies);
				engine.searchDeclarationsOfReferencedTypes(element, getCollector(), new SubProgressMonitor(monitor, 1, SubProgressMonitor.SUPPRESS_SUBTASK_LABEL));
			} catch (CoreException exception) {
				throw new JavaModelException(exception);
			}
		} finally {
			monitor.done();
		}
	}

	/**
	 * Determines how search matches are filtered.
	 * <p>
	 * This method must be called before start searching. The default is to filter inaccurate matches only.
	 *
	 * @param inaccurate <code>true</code> to filter inaccurate matches, <code>false</code> otherwise
	 * @param binary <code>true</code> to filter binary matches, <code>false</code> otherwise
	 */
	public final void setFiltering(final boolean inaccurate, final boolean binary) {
		fInaccurate= inaccurate;
		fBinary= binary;
	}

	/**
	 * Sets the granularity to use during the searches.
	 * <p>
	 * This method must be called before start searching. The default is a granularity of {@link #GRANULARITY_SEARCH_MATCH}.
	 *
	 * @param granularity The granularity to use. Must be one of the <code>GRANULARITY_XXX</code> constants.
	 */
	public final void setGranularity(final int granularity) {
		Assert.isTrue(granularity == GRANULARITY_COMPILATION_UNIT || granularity == GRANULARITY_SEARCH_MATCH);
		fGranularity= granularity;
	}

	/**
	 * Sets the working copies to take precedence during the searches.
	 * <p>
	 * This method must be called before start searching. The default is to use no working copies
	 *
	 * @param copies the working copies to use
	 */
	public final void setWorkingCopies(final ICompilationUnit[] copies) {
		Assert.isNotNull(copies);
		fWorkingCopies= new ICompilationUnit[copies.length];
		System.arraycopy(copies, 0, fWorkingCopies, 0, copies.length);
	}

	/**
	 * Determines how search matches are grouped.
	 * <p>
	 * This method must be called before start searching. The default is to group by containing resource.
	 *
	 * @param grouping <code>true</code> to group matches by their containing resource, <code>false</code> otherwise
	 */
	public final void setGrouping(final boolean grouping) {
		fGrouping= grouping;
	}

	/**
	 * Sets the disjunction of search patterns to be used during search.
	 * <p>
	 * This method must be called before {@link RefactoringSearchEngine2#searchPattern(IProgressMonitor)}
	 *
	 * @param first the first search pattern to set
	 * @param second the second search pattern to set
	 */
	public final void setOrPattern(final SearchPattern first, final SearchPattern second) {
		Assert.isNotNull(first);
		Assert.isNotNull(second);
		fPattern= SearchPattern.createOrPattern(first, second);
	}

	/**
	 * Sets the working copy owner to use during search.
	 * <p>
	 * This method must be called before start searching. The default is to use no working copy owner.
	 *
	 * @param owner the working copy owner to use, or <code>null</code> to use none
	 */
	public final void setOwner(final WorkingCopyOwner owner) {
		fOwner= owner;
	}

	/**
	 * Sets the search pattern to be used during search.
	 * <p>
	 * This method must be called before {@link RefactoringSearchEngine2#searchPattern(IProgressMonitor)}
	 *
	 * @param elements the set of elements
	 * @param limitTo determines the nature of the expected matches. This is a combination of {@link org.eclipse.jdt.core.search.IJavaSearchConstants}.
	 */
	public final void setPattern(final IJavaElement[] elements, final int limitTo) {
		Assert.isNotNull(elements);
		Assert.isTrue(elements.length > 0);
		SearchPattern pattern= SearchPattern.createPattern(elements[0], limitTo, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE);
		IJavaElement element= null;
		for (int index= 1; index < elements.length; index++) {
			element= elements[index];
			pattern= SearchPattern.createOrPattern(pattern, SearchPattern.createPattern(element, limitTo, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE));
		}
		setPattern(pattern);
	}

	/**
	 * Sets the search pattern to be used during search.
	 * <p>
	 * This method must be called before {@link RefactoringSearchEngine2#searchPattern(IProgressMonitor)}
	 *
	 * @param pattern the search pattern to set
	 */
	public final void setPattern(final SearchPattern pattern) {
		Assert.isNotNull(pattern);
		fPattern= pattern;
	}

	/**
	 * Sets the search requestor for this search engine.
	 * <p>
	 * This method must be called before start searching. The default is a non-filtering search requestor.
	 *
	 * @param requestor the search requestor to set
	 */
	public final void setRequestor(final IRefactoringSearchRequestor requestor) {
		Assert.isNotNull(requestor);
		fRequestor= requestor;
	}

	/**
	 * Sets the search scope for this search engine.
	 * <p>
	 * This method must be called before start searching. The default is the entire workspace as search scope.
	 *
	 * @param scope the search scope to set
	 */
	public final void setScope(final IJavaSearchScope scope) {
		Assert.isNotNull(scope);
		fScope= scope;
	}

	/**
	 * Sets the severity of the generated status entries.
	 * <p>
	 * This method must be called before start searching. The default is a severity of {@link RefactoringStatus#OK}.
	 *
	 * @param severity the severity to set
	 */
	public final void setSeverity(final int severity) {
		Assert.isTrue(severity == RefactoringStatus.WARNING || severity == RefactoringStatus.INFO || severity == RefactoringStatus.FATAL || severity == RefactoringStatus.ERROR);
		fSeverity= severity;
	}

	/**
	 * Sets the refactoring status for this search engine.
	 * <p>
	 * This method must be called before start searching. The default is an empty status with status {@link RefactoringStatus#OK}.
	 *
	 * @param status the refactoring status to set
	 */
	public final void setStatus(final RefactoringStatus status) {
		Assert.isNotNull(status);
		fStatus= status;
	}
}
