/*******************************************************************************
 * Copyright (c) 2000, 2020 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.core.tests.model;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.runtime.*;
import org.eclipse.jdt.core.*;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.core.search.*;
import org.eclipse.jdt.core.tests.model.Semaphore.TimeOutException;
import org.eclipse.jdt.core.tests.util.Util;
import org.eclipse.jdt.internal.core.JavaElement;
import org.eclipse.jdt.internal.core.JavaModelManager;
import org.eclipse.jdt.internal.core.LocalVariable;
import org.eclipse.jdt.internal.core.search.BasicSearchEngine;
import org.eclipse.jdt.internal.core.search.indexing.IndexManager;
import org.eclipse.jdt.internal.core.search.processing.IJob;

import junit.framework.Test;

/*
 * Test indexing support.
 */
public class SearchTests extends ModifyingResourceTests implements IJavaSearchConstants {
	/*
	 * Empty jar contents.
	 * Generated using the following code:

	 	String filePath = "d:\\temp\\empty.jar";
		new JarOutputStream(new FileOutputStream(filePath), new Manifest()).close();
		byte[] contents = org.eclipse.jdt.internal.compiler.util.Util.getFileByteContent(new File(filePath));
		System.out.print("{");
		for (int i = 0, length = contents.length; i < length; i++) {
			System.out.print(contents[i]);
			System.out.print(", ");
		}
		System.out.print("}");
	 */
	static final byte[] EMPTY_JAR = {80, 75, 3, 4, 20, 0, 8, 0, 8, 0, 106, -100, 116, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 4, 0, 77, 69, 84, 65, 45, 73, 78, 70, 47, 77, 65, 78, 73, 70, 69, 83, 84, 46, 77, 70, -2, -54, 0, 0, -29, -27, 2, 0, 80, 75, 7, 8, -84, -123, -94, 20, 4, 0, 0, 0, 2, 0, 0, 0, 80, 75, 1, 2, 20, 0, 20, 0, 8, 0, 8, 0, 106, -100, 116, 46, -84, -123, -94, 20, 4, 0, 0, 0, 2, 0, 0, 0, 20, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 69, 84, 65, 45, 73, 78, 70, 47, 77, 65, 78, 73, 70, 69, 83, 84, 46, 77, 70, -2, -54, 0, 0, 80, 75, 5, 6, 0, 0, 0, 0, 1, 0, 1, 0, 70, 0, 0, 0, 74, 0, 0, 0, 0, 0, };
	class WaitUntilReadyMonitor implements IProgressMonitor {
		public Semaphore sem = new Semaphore();
		public void beginTask(String name, int totalWork) {
		}
		public void internalWorked(double work) {
		}
		public void done() {
		}
		public boolean isCanceled() {
			return false;
		}
		public void setCanceled(boolean value) {
		}
		public void setTaskName(String name) {
		}
		public void subTask(String name) {
			// concurrent job is signaling it is working
			this.sem.release();
		}
		public void worked(int work) {
		}
	}
	public static class SearchMethodNameRequestor extends MethodNameRequestor {
		List<String> results = new ArrayList<>();
		@Override
		public void acceptMethod(
				char[] methodName,
				int parameterCount,
				char[] declaringQualifier,
				char[] simpleTypeName,
				int typeModifiers,
				char[] packageName,
				char[] signature,
				char[][] parameterTypes,
				char[][] parameterNames,
				char[] returnType,
				int modifiers,
				String path,
				int methodIndex) {
			StringBuffer buffer = new StringBuffer();
			char c = '.';
			char[] noname = new String("<NONAME>").toCharArray();
			buffer.append(path);
			buffer.append(' ');
			buffer.append(returnType == null ? CharOperation.NO_CHAR: returnType);
			buffer.append(' ');
			checkAndAddtoBuffer(buffer, packageName, c);
			checkAndAddtoBuffer(buffer, declaringQualifier, c);
			checkAndAddtoBuffer(buffer, simpleTypeName == null ? noname : simpleTypeName, c);
			buffer.append(methodName);
			buffer.append('(');
			parameterTypes = signature == null ? parameterTypes : Signature.getParameterTypes(signature);

			for (int i = 0; i < parameterCount; i++) {

				if (parameterTypes != null) {
					char[] parameterType;
					if (parameterTypes.length != parameterCount) {
						System.out.println("Error");
					}
					if (signature != null) {
						parameterType = Signature.toCharArray(Signature.getTypeErasure(parameterTypes[i]));
						CharOperation.replace(parameterType, '/', '.');
					} else {
						parameterType = parameterTypes[i];
					}
					buffer.append(parameterType);
				} else {
					buffer.append('?'); // parameter type names are not stored in the indexes
					buffer.append('?');
					buffer.append('?');
				}
				buffer.append(' ');
				if (parameterNames != null) {
					buffer.append(parameterNames[i]);
				} else {
					buffer.append("arg"+i);
				}
				if (parameterCount > 1 && i < parameterCount - 1) buffer.append(',');
			}
			buffer.append(')');
			this.results.add(buffer.toString());
		}
		static void checkAndAddtoBuffer(StringBuffer buffer, char[] precond, char c) {
			if (precond == null || precond.length == 0) return;
			buffer.append(precond);
			buffer.append(c);
		}
		public String toString(){
			int length = this.results.size();
			String[] strings = new String[length];
			this.results.toArray(strings);
			org.eclipse.jdt.internal.core.util.Util.sort(strings);
			StringBuffer buffer = new StringBuffer(100);
			for (int i = 0; i < length; i++){
				buffer.append(strings[i]);
				if (i != length-1) {
					buffer.append('\n');
				}
			}
			return buffer.toString();
		}
		public int size() {
			return this.results.size();
		}
	}
	public static class SearchTypeNameRequestor extends TypeNameRequestor {
		List<String> results = new ArrayList<>();
		public void acceptType(int modifiers, char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path) {
			char[] typeName =
				CharOperation.concat(
					CharOperation.concatWith(enclosingTypeNames, '$'),
					simpleTypeName,
					'$');
			this.results.add(new String(CharOperation.concat(packageName, typeName, '.')));
		}
		public String toString(){
			int length = this.results.size();
			String[] strings = new String[length];
			this.results.toArray(strings);
			org.eclipse.jdt.internal.core.util.Util.sort(strings);
			StringBuffer buffer = new StringBuffer(100);
			for (int i = 0; i < length; i++){
				buffer.append(strings[i]);
				if (i != length-1) {
					buffer.append('\n');
				}
			}
			return buffer.toString();
		}
		public String unsortedString() {
			int length = this.results.size();
			String[] strings = new String[length];
			this.results.toArray(strings);
			StringBuffer buffer = new StringBuffer(100);
			for (int i = 0; i < length; i++){
				buffer.append(strings[i]);
				if (i != length-1) {
					buffer.append('\n');
				}
			}
			return buffer.toString();
		}
		public int size() {
			return this.results.size();
		}
	}
	static class WaitingJob implements IJob {
		private static final int MAX_WAIT = 30000; // wait 30s max
		private Semaphore startingSem = new Semaphore();
		private Semaphore runningSem = new Semaphore();
		public boolean belongsTo(String jobFamily) {
			return false;
		}
		public void cancel() {
		}
		public void ensureReadyToRun() {
		}
		public boolean execute(IProgressMonitor progress) {
			this.startingSem.release();
			try {
				this.runningSem.acquire(MAX_WAIT);
			} catch (TimeOutException e) {
				e.printStackTrace();
			}
			return true;
		}
		public String getJobFamily() {
			return "SearchTests.Waiting";
		}
		public void suspend() throws Semaphore.TimeOutException, CoreException {
	 		runAndSuspend(null);
		}
		public void runAndSuspend(IWorkspaceRunnable runnable) throws Semaphore.TimeOutException, CoreException {
	 		IndexManager indexManager = JavaModelManager.getIndexManager();
			indexManager.disable();
			if (runnable != null) {
				runnable.run(null);
			}
			indexManager.request(this);
			indexManager.enable();
			this.startingSem.acquire(30000); // wait for job to start (wait 30s max)
		}

		public void resume() {
			this.runningSem.release();
			JavaModelManager.getIndexManager().enable();
		}
	}
static {
	//TESTS_PREFIX = "testSearchPatternValidateMatchRule";
}
public static Test suite() {
	return buildModelTestSuite(SearchTests.class);
}


public SearchTests(String name) {
	super(name);
}
protected void assertAllTypes(int waitingPolicy, IProgressMonitor progressMonitor, String expected) throws JavaModelException {
	assertAllTypes("Unexpected all types", null/* no specific project*/, waitingPolicy, progressMonitor, expected);
}
protected void assertAllTypes(String expected) throws JavaModelException {
	assertAllTypes(WAIT_UNTIL_READY_TO_SEARCH, null/* no progress monitor*/, expected);
}
protected void assertAllTypes(String message, IJavaProject project, String expected) throws JavaModelException {
	assertAllTypes(message, project, WAIT_UNTIL_READY_TO_SEARCH, null/* no progress monitor*/, expected);
}
protected void assertAllTypes(String message, IJavaProject project, int waitingPolicy, IProgressMonitor progressMonitor, String expected) throws JavaModelException {
	IJavaSearchScope scope =
		project == null ?
			SearchEngine.createWorkspaceScope() :
			SearchEngine.createJavaSearchScope(new IJavaElement[] {project});
	SearchEngine searchEngine = new SearchEngine();
	SearchTypeNameRequestor requestor = new SearchTypeNameRequestor();
	searchEngine.searchAllTypeNames(
		null,
		SearchPattern.R_EXACT_MATCH,
		null,
		SearchPattern.R_PATTERN_MATCH, // case insensitive
		TYPE,
		scope,
		requestor,
		waitingPolicy,
		progressMonitor);
	String actual = requestor.toString();
	if (!expected.equals(actual)){
	 	System.out.println(Util.displayString(actual, 3));
	}
	assertEquals(
		message,
		expected,
		actual);
}
protected void assertPattern(String expected, SearchPattern actualPattern) {
	String actual = actualPattern == null ? null : actualPattern.toString();
	if (!expected.equals(actual)) {
		System.out.print(actual == null ? "null" : Util.displayString(actual, 2));
		System.out.println(",");
	}
	assertEquals(
		"Unexpected search pattern",
		expected,
		actual);
}
protected void assertValidMatchRule(String pattern, int rule) {
	assertValidMatchRule(pattern, rule, rule);
}
protected void assertValidMatchRule(String pattern, int rule, int expected) {
	int validated = SearchPattern.validateMatchRule(pattern, rule);
	String givenRule = BasicSearchEngine.getMatchRuleString(rule);
	String validatedRule = BasicSearchEngine.getMatchRuleString(validated);
	String expectedRule = BasicSearchEngine.getMatchRuleString(expected);
	if (!validatedRule.equals(expectedRule)) {
		System.out.println("Test "+getName());
		System.out.print("	assertValidMatchRule(\"");
		System.out.print(pattern);
		System.out.println("\",");
		System.out.print("		SearchPattern.");
		System.out.print(givenRule);
		System.out.println("\",");
		System.out.print("		SearchPattern.");
		System.out.print(validatedRule);
		System.out.println(");");
		assertEquals(pattern+"' does not match expected match rule!", expectedRule, validatedRule);
	}
}
@Override
public void setUpSuite() throws Exception {
	super.setUpSuite();
	createJavaProject("P");
	createFolder("/P/x/y/z");
	createFile(
		"/P/x/y/z/Foo.java",
		"package x.y,z;\n" +
		"import x.y.*;\n" +
		"import java.util.Vector;\n" +
		"public class Foo {\n" +
		"  int field;\n" +
		"  void bar() {\n" +
		"  }\n" +
		"}"
	);
	createFile(
		"/P/x/y/z/I.java",
		"package x.y,z;\n" +
		"public interface I {\n" +
		"}"
	);
}
@Override
public void tearDownSuite() throws Exception {
	deleteProject("P");
	super.tearDownSuite();
}
/*
 * Ensure that changing the classpath in the middle of reindexing
 * a project causes another request to reindex.
 */
public void testChangeClasspath() throws CoreException, TimeOutException {
	WaitingJob job = new WaitingJob();
	try {
		// setup: suspend indexing and create a project (prj=src) with one cu
		job.runAndSuspend(new IWorkspaceRunnable() {
			public void run(IProgressMonitor monitor) throws CoreException {
				JavaCore.run(new IWorkspaceRunnable() {
					public void run(IProgressMonitor monitor2) throws CoreException {
						createJavaProject("P1");
						createFile(
							"/P1/X.java",
							"public class X {\n" +
							"}"
						);
					}
				}, monitor);
			}
		});

		// remove source folder from classpath
		IJavaProject project = getJavaProject("P1");
		project.setRawClasspath(
			new IClasspathEntry[0],
			null);

		// resume waiting job
		job.resume();

		assertAllTypes(
			"Unexpected all types after removing source folder",
			project,
			""
		);
	} finally {
		job.resume();
		deleteProject("P1");
	}
}
/*
 * Ensure that removing a project source folder and adding another source folder removes the existing cus from the index
 * (regression test for bug 73356 Index not updated after adding a source folder
 */
public void testChangeClasspath2() throws CoreException {
	try {
		final IJavaProject project = createJavaProject("P1", new String[] {""}, "bin");
		createFile(
			"/P1/X.java",
			"public class X {}"
		);
		assertAllTypes(
			"Unexpected types before changing the classpath",
			null, // workspace search
			"X\n" +
			"java.io.Serializable\n" +
			"java.lang.Class\n" +
			"java.lang.CloneNotSupportedException\n" +
			"java.lang.Error\n" +
			"java.lang.Exception\n" +
			"java.lang.IllegalMonitorStateException\n" +
			"java.lang.InterruptedException\n" +
			"java.lang.Object\n" +
			"java.lang.RuntimeException\n" +
			"java.lang.String\n" +
			"java.lang.Throwable\n" +
			"x.y.Foo\n" +
			"x.y.I"
		);
		getWorkspace().run(new IWorkspaceRunnable() {
			public void run(IProgressMonitor monitor) throws CoreException {
				createFolder("/P1/src");
				project.setRawClasspath(createClasspath(new String[] {"/P1/src"}, false, false), null);
			}
		}, null);
		assertAllTypes(
			"Unexpected types after changing the classpath",
			null, // workspace search
			"java.io.Serializable\n" +
			"java.lang.Class\n" +
			"java.lang.CloneNotSupportedException\n" +
			"java.lang.Error\n" +
			"java.lang.Exception\n" +
			"java.lang.IllegalMonitorStateException\n" +
			"java.lang.InterruptedException\n" +
			"java.lang.Object\n" +
			"java.lang.RuntimeException\n" +
			"java.lang.String\n" +
			"java.lang.Throwable\n" +
			"x.y.Foo\n" +
			"x.y.I"
		);
	} finally {
		deleteProject("P1");
	}
}
/*
 * Ensure that performing a concurrent job while indexing a jar doesn't use the old index.
 * (regression test for bug 35306 Index update request can be incorrectly handled)
 */
public void testConcurrentJob() throws CoreException, InterruptedException, IOException, TimeOutException {
	WaitingJob job = new WaitingJob();
	try {
		// setup: suspend indexing and create a project with one empty jar on its classpath
		job.runAndSuspend(new IWorkspaceRunnable() {
			public void run(IProgressMonitor monitor) throws CoreException {
				JavaCore.run(new IWorkspaceRunnable() {
					public void run(IProgressMonitor monitor2) throws CoreException {
						createJavaProject("P1", new String[] {}, new String[] {"/P1/jclMin.jar"}, "bin");
						createFile("/P1/jclMin.jar", EMPTY_JAR);
					}
				}, monitor);
			}
		});

		final IJavaProject project = getJavaProject("P1");

		// start concurrent job
		final boolean[] success = new boolean[1];
		final WaitUntilReadyMonitor monitor = new WaitUntilReadyMonitor();
		Thread thread = new Thread() {
			@Override
			public void run() {
				try {
					assertAllTypes(
						"Unexpected all types",
						project,
						WAIT_UNTIL_READY_TO_SEARCH,
						monitor,
						"java.io.Serializable\n" +
						"java.lang.Class\n" +
						"java.lang.CloneNotSupportedException\n" +
						"java.lang.Error\n" +
						"java.lang.Exception\n" +
						"java.lang.IllegalMonitorStateException\n" +
						"java.lang.InterruptedException\n" +
						"java.lang.Object\n" +
						"java.lang.RuntimeException\n" +
						"java.lang.String\n" +
						"java.lang.Throwable"
					);
				} catch (JavaModelException e) {
					e.printStackTrace();
					return;
				}
				success[0] = true;
			}
		};
		thread.setDaemon(true);
		thread.start();

		// wait for concurrent job to start
		monitor.sem.acquire(30000); // wait 30s max

		// change jar contents
		getFile("/P1/jclMin.jar").setContents(new FileInputStream(getExternalJCLPathString()), IResource.NONE, null);
			// setContents closes the stream

		// resume waiting job
		job.resume();

		// wait for concurrent job to finish
		thread.join(10000); // 10s max

		assertTrue("Failed to get all types", success[0]);

	} finally {
		job.resume();
		deleteProject("P1");
	}
}
/*
 * Ensures that passing a null progress monitor with a CANCEL_IF_NOT_READY_TO_SEARCH
 * waiting policy doesn't throw a NullPointerException but an OperationCanceledException.
 * (regression test for bug 33571 SearchEngine.searchAllTypeNames: NPE when passing null as progress monitor)
 */
 public void testNullProgressMonitor() throws CoreException, TimeOutException {
	WaitingJob job = new WaitingJob();
 	try {
 		job.suspend();

		// query all type names with a null progress monitor
		boolean operationCanceled = false;
		try {
			assertAllTypes(
				CANCEL_IF_NOT_READY_TO_SEARCH,
				null, // null progress monitor
				"Should not get any type"
			);
		} catch (OperationCanceledException e) {
			operationCanceled = true;
		}
		assertTrue("Should throw an OperationCanceledException", operationCanceled);
 	} finally {
 		job.resume();
 	}
 }
 /*
  * Ensures that types are found if the project is a lib folder
  * (regression test for bug 83822 Classes at root of project not found in Open Type dialog)
  */
 public void testProjectLib() throws CoreException {
 	try {
 		IJavaProject javaProject = createJavaProject("P1", new String[0], new String[] {"/P1"}, "bin");
 		createClassFile("/P1", "X.class", "public class X {}");
 		IProject project = javaProject.getProject();
 		project.close(null);
 		waitUntilIndexesReady();
 		project.open(null);
 		assertAllTypes(
 			"Unexpected types in P1",
 			javaProject,
 			"X"
 		);
 	} finally {
 		deleteProject("P1");
 	}
 }
/*
 * Ensure that removing the outer folder from the classpath doesn't remove cus in inner folder
 * from index
 * (regression test for bug 32607 Removing outer folder removes nested folder's cus from index)
 */
public void testRemoveOuterFolder() throws CoreException {
	try {
		// setup: one cu in a nested source folder
		JavaCore.run(new IWorkspaceRunnable() {
			public void run(IProgressMonitor monitor) throws CoreException {
				IJavaProject project = createJavaProject("P1");
				project.setRawClasspath(
					createClasspath(new String[] {"/P1/src1", "src2/", "/P1/src1/src2", ""}, false/*no inclusion*/, true/*exclusion*/),
					new Path("/P1/bin"),
					null);
				createFolder("/P1/src1/src2");
				createFile(
					"/P1/src1/src2/X.java",
					"public class X {\n" +
					"}"
				);
			}
		}, null);
		IJavaProject project = getJavaProject("P1");
		assertAllTypes(
			"Unexpected all types after setup",
			project,
			"X"
		);

		// remove outer folder from classpath
		project.setRawClasspath(
			createClasspath(new String[] {"/P1/src1/src2", ""}, false/*no inclusion*/, true/*exclusion*/),
			null);
		assertAllTypes(
			"Unexpected all types after removing outer folder",
			project,
			"X"
		);

	} finally {
		deleteProject("P1");
	}
}
/**
 * Test pattern creation
 */
public void testSearchPatternCreation01() {

	SearchPattern searchPattern = createPattern(
			"main(*)",
			IJavaSearchConstants.METHOD,
			IJavaSearchConstants.REFERENCES,
			true); // case sensitive

	assertPattern(
		"MethodReferencePattern: main(*), pattern match, case sensitive, generic full match, fine grain: none",
		searchPattern);
}

/**
 * Test pattern creation
 */
public void testSearchPatternCreation02() {

	SearchPattern searchPattern = createPattern(
			"main(*) void",
			IJavaSearchConstants.METHOD,
			IJavaSearchConstants.REFERENCES,
			true); // case sensitive

	assertPattern(
		"MethodReferencePattern: main(*) --> void, pattern match, case sensitive, generic full match, fine grain: none",
		searchPattern);
}

/**
 * Test pattern creation
 */
public void testSearchPatternCreation03() {

	SearchPattern searchPattern = createPattern(
			"main(String*) void",
			IJavaSearchConstants.METHOD,
			IJavaSearchConstants.REFERENCES,
			true); // case sensitive

	assertPattern(
		"MethodReferencePattern: main(String*) --> void, pattern match, case sensitive, generic full match, fine grain: none",
		searchPattern);
}

/**
 * Test pattern creation
 */
public void testSearchPatternCreation04() {

	SearchPattern searchPattern = createPattern(
			"main(*[])",
			IJavaSearchConstants.METHOD,
			IJavaSearchConstants.REFERENCES,
			true); // case sensitive

	assertPattern(
		"MethodReferencePattern: main(*[]), pattern match, case sensitive, generic full match, fine grain: none",
		searchPattern);
}

/**
 * Test pattern creation
 */
public void testSearchPatternCreation05() {

	SearchPattern searchPattern = createPattern(
			"java.lang.*.main ",
			IJavaSearchConstants.METHOD,
			IJavaSearchConstants.REFERENCES,
			true); // case sensitive

	assertPattern(
		"MethodReferencePattern: java.lang.*.main(...), pattern match, case sensitive, generic full match, fine grain: none",
		searchPattern);
}

/**
 * Test pattern creation
 */
public void testSearchPatternCreation06() {

	SearchPattern searchPattern = createPattern(
			"java.lang.* ",
			IJavaSearchConstants.CONSTRUCTOR,
			IJavaSearchConstants.REFERENCES,
			true); // case sensitive

	assertPattern(
		"ConstructorReferencePattern: java.lang.*(...), pattern match, case sensitive, generic full match, fine grain: none",
		searchPattern);
}

/**
 * Test pattern creation
 */
public void testSearchPatternCreation07() {

	SearchPattern searchPattern = createPattern(
			"X(*,*)",
			IJavaSearchConstants.CONSTRUCTOR,
			IJavaSearchConstants.REFERENCES,
			true); // case sensitive

	assertPattern(
		"ConstructorReferencePattern: X(*, *), pattern match, case sensitive, generic full match, fine grain: none",
		searchPattern);
}

/**
 * Test pattern creation
 */
public void testSearchPatternCreation08() {

	SearchPattern searchPattern = createPattern(
			"main(String*,*) void",
			IJavaSearchConstants.METHOD,
			IJavaSearchConstants.REFERENCES,
			true); // case sensitive

	assertPattern(
		"MethodReferencePattern: main(String*, *) --> void, pattern match, case sensitive, generic full match, fine grain: none",
		searchPattern);
}

/**
 * Test pattern creation
 */
public void testSearchPatternCreation10() {

	SearchPattern searchPattern = createPattern(
			"x.y.z.Bar.field Foo",
			IJavaSearchConstants.FIELD,
			IJavaSearchConstants.DECLARATIONS,
			true); // case sensitive

	assertPattern(
		"FieldDeclarationPattern: x.y.z.Bar.field --> Foo, exact match, case sensitive, generic full match, fine grain: none",
		searchPattern);
}

/**
 * Test pattern creation
 */
public void testSearchPatternCreation12() {
	IField field = getCompilationUnit("/P/x/y/z/Foo.java").getType("Foo").getField("field");
	SearchPattern searchPattern = createPattern(
			field,
			IJavaSearchConstants.REFERENCES);

	assertPattern(
		"FieldReferencePattern: x.y.z.Foo.field --> int, exact match, case sensitive, generic erasure match, fine grain: none",
		searchPattern);
}

/**
 * Test pattern creation
 */
public void testSearchPatternCreation13() {
	IField field = getCompilationUnit("/P/x/y/z/Foo.java").getType("Foo").getField("field");
	SearchPattern searchPattern = createPattern(
			field,
			IJavaSearchConstants.DECLARATIONS);

	assertPattern(
		"FieldDeclarationPattern: x.y.z.Foo.field --> int, exact match, case sensitive, generic erasure match, fine grain: none",
		searchPattern);
}

/**
 * Test pattern creation
 */
public void testSearchPatternCreation14() {
	IField field = getCompilationUnit("/P/x/y/z/Foo.java").getType("Foo").getField("field");
	SearchPattern searchPattern = createPattern(
			field,
			IJavaSearchConstants.ALL_OCCURRENCES);

	assertPattern(
		"FieldCombinedPattern: x.y.z.Foo.field --> int, exact match, case sensitive, generic erasure match, fine grain: none",
		searchPattern);
}

/**
 * Test pattern creation
 */
public void testSearchPatternCreation15() {
	IImportDeclaration importDecl = getCompilationUnit("/P/x/y/z/Foo.java").getImport("x.y.*");
	SearchPattern searchPattern = createPattern(
			importDecl,
			IJavaSearchConstants.REFERENCES);

	assertPattern(
		"PackageReferencePattern: <x.y>, exact match, case sensitive, generic erasure match, fine grain: none",
		searchPattern);
}

/**
 * Test pattern creation
 */
public void testSearchPatternCreation16() {
	IMethod method = getCompilationUnit("/P/x/y/z/Foo.java").getType("Foo").getMethod("bar", new String[] {});
	SearchPattern searchPattern = createPattern(
			method,
			IJavaSearchConstants.DECLARATIONS);

	assertPattern(
		"MethodDeclarationPattern: x.y.z.Foo.bar() --> void, exact match, case sensitive, generic erasure match, fine grain: none",
		searchPattern);
}

/**
 * Test pattern creation
 */
public void testSearchPatternCreation17() {
	IMethod method = getCompilationUnit("/P/x/y/z/Foo.java").getType("Foo").getMethod("bar", new String[] {});
	SearchPattern searchPattern = createPattern(
			method,
			IJavaSearchConstants.REFERENCES);

	assertPattern(
		"MethodReferencePattern: x.y.z.Foo.bar() --> void, exact match, case sensitive, generic erasure match, fine grain: none",
		searchPattern);
}

/**
 * Test pattern creation
 */
public void testSearchPatternCreation18() {
	IMethod method = getCompilationUnit("/P/x/y/z/Foo.java").getType("Foo").getMethod("bar", new String[] {});
	SearchPattern searchPattern = createPattern(
			method,
			IJavaSearchConstants.ALL_OCCURRENCES);

	assertPattern(
		"MethodCombinedPattern: x.y.z.Foo.bar() --> void, exact match, case sensitive, generic erasure match, fine grain: none",
		searchPattern);
}

/**
 * Test pattern creation
 */
public void testSearchPatternCreation19() {
	IType type = getCompilationUnit("/P/x/y/z/Foo.java").getType("Foo");
	SearchPattern searchPattern = createPattern(
			type,
			IJavaSearchConstants.DECLARATIONS);

	assertPattern(
		"TypeDeclarationPattern: pkg<x.y.z>, enclosing<>, type<Foo>, exact match, case sensitive, generic erasure match, fine grain: none",
		searchPattern);
}

/**
 * Test pattern creation
 */
public void testSearchPatternCreation20() {
	IType type = getCompilationUnit("/P/x/y/z/Foo.java").getType("Foo");
	SearchPattern searchPattern = createPattern(
			type,
			IJavaSearchConstants.REFERENCES);

	assertPattern(
		"TypeReferencePattern: qualification<x.y.z>, type<Foo>, exact match, case sensitive, generic erasure match, fine grain: none",
		searchPattern);
}

/**
 * Test pattern creation
 */
public void testSearchPatternCreation21() {
	IType type = getCompilationUnit("/P/x/y/z/I.java").getType("I");
	SearchPattern searchPattern = createPattern(
			type,
			IJavaSearchConstants.IMPLEMENTORS);

	assertPattern(
		"SuperInterfaceReferencePattern: <I>, exact match, case sensitive, generic erasure match, fine grain: none",
		searchPattern);
}

/**
 * Test pattern creation
 */
public void testSearchPatternCreation22() {
	IType type = getCompilationUnit("/P/x/y/z/Foo.java").getType("Foo");
	SearchPattern searchPattern = createPattern(
			type,
			IJavaSearchConstants.ALL_OCCURRENCES);

	assertPattern(
		"TypeDeclarationPattern: pkg<x.y.z>, enclosing<>, type<Foo>, exact match, case sensitive, generic erasure match, fine grain: none\n" +
		"| TypeReferencePattern: qualification<x.y.z>, type<Foo>, exact match, case sensitive, generic erasure match, fine grain: none",
		searchPattern);
}

/**
 * Test pattern creation
 */
public void testSearchPatternCreation23() {
	IPackageDeclaration pkg = getCompilationUnit("/P/x/y/z/Foo.java").getPackageDeclaration("x.y.z");
	SearchPattern searchPattern = createPattern(
			pkg,
			IJavaSearchConstants.REFERENCES);

	assertPattern(
		"PackageReferencePattern: <x.y.z>, exact match, case sensitive, generic erasure match, fine grain: none",
		searchPattern);
}

/**
 * Test pattern creation
 */
public void testSearchPatternCreation24() {
	IPackageFragment pkg = getPackage("/P/x/y/z");
	SearchPattern searchPattern = createPattern(
			pkg,
			IJavaSearchConstants.REFERENCES);

	assertPattern(
		"PackageReferencePattern: <x.y.z>, exact match, case sensitive, generic erasure match, fine grain: none",
		searchPattern);
}

/**
 * Test pattern creation
 */
public void testSearchPatternCreation25() {
	IImportDeclaration importDecl = getCompilationUnit("/P/x/y/z/Foo.java").getImport("java.util.Vector");
	SearchPattern searchPattern = createPattern(
			importDecl,
			IJavaSearchConstants.REFERENCES);

	assertPattern(
		"TypeReferencePattern: qualification<java.util>, type<Vector>, exact match, case sensitive, generic erasure match, fine grain: none",
		searchPattern);
}

/**
 * Test pattern creation
 */
public void testSearchPatternCreation26() {
	IPackageFragment pkg = getPackage("/P/x/y/z");
	SearchPattern searchPattern = createPattern(
			pkg,
			IJavaSearchConstants.DECLARATIONS);

	assertPattern(
		"PackageDeclarationPattern: <x.y.z>, exact match, case sensitive, generic erasure match, fine grain: none",
		searchPattern);
}

/**
 * Test pattern creation
 */
public void testSearchPatternCreation27() {
	IPackageDeclaration pkg = getCompilationUnit("/P/x/y/z/Foo.java").getPackageDeclaration("x.y.z");
	SearchPattern searchPattern = createPattern(
			pkg,
			IJavaSearchConstants.DECLARATIONS);

	assertPattern(
		"PackageDeclarationPattern: <x.y.z>, exact match, case sensitive, generic erasure match, fine grain: none",
		searchPattern);
}

/**
 * Test pattern creation
 */
public void testSearchPatternCreation28() {
	IImportDeclaration importDecl = getCompilationUnit("/P/x/y/z/Foo.java").getImport("x.y.*");
	SearchPattern searchPattern = createPattern(
			importDecl,
			IJavaSearchConstants.DECLARATIONS);

	assertPattern(
		"PackageDeclarationPattern: <x.y>, exact match, case sensitive, generic erasure match, fine grain: none",
		searchPattern);
}

/**
 * Test pattern creation
 */
public void testSearchPatternCreation29() {
	IPackageFragment pkg = getPackage("/P/x/y/z");
	SearchPattern searchPattern = createPattern(
			pkg,
			IJavaSearchConstants.ALL_OCCURRENCES);

	assertPattern(
		"PackageDeclarationPattern: <x.y.z>, exact match, case sensitive, generic erasure match, fine grain: none\n" +
		"| PackageReferencePattern: <x.y.z>, exact match, case sensitive, generic erasure match, fine grain: none",
		searchPattern);
}

/**
 * Test LocalVarDeclarationPattern creation
 */
public void testSearchPatternCreation30() {
	ILocalVariable localVar = new LocalVariable((JavaElement)getCompilationUnit("/P/X.java").getType("X").getMethod("foo", new String[0]),  "var", 1, 2, 3, 4, "Z", null, 0, false);
	SearchPattern searchPattern = createPattern(
			localVar,
			IJavaSearchConstants.DECLARATIONS);

	assertPattern(
		"LocalVarDeclarationPattern: var [in foo() [in X [in X.java [in <default> [in <project root> [in P]]]]]], exact match, case sensitive, generic erasure match, fine grain: none",
		searchPattern);
}

/**
 * Test LocalVarReferencePattern creation
 */
public void testSearchPatternCreation31() {
	ILocalVariable localVar = new LocalVariable((JavaElement)getCompilationUnit("/P/X.java").getType("X").getMethod("foo", new String[0]),  "var", 1, 2, 3, 4, "Z", null, 0, false);
	SearchPattern searchPattern = createPattern(
			localVar,
			IJavaSearchConstants.REFERENCES);

	assertPattern(
		"LocalVarReferencePattern: var [in foo() [in X [in X.java [in <default> [in <project root> [in P]]]]]], exact match, case sensitive, generic erasure match, fine grain: none",
		searchPattern);
}

/**
 * Test LocalVarCombinedPattern creation
 */
public void testSearchPatternCreation32() {
	ILocalVariable localVar = new LocalVariable((JavaElement)getCompilationUnit("/P/X.java").getType("X").getMethod("foo", new String[0]),  "var", 1, 2, 3, 4, "Z", null, 0, false);
	SearchPattern searchPattern = createPattern(
			localVar,
			IJavaSearchConstants.ALL_OCCURRENCES);

	assertPattern(
		"LocalVarCombinedPattern: var [in foo() [in X [in X.java [in <default> [in <project root> [in P]]]]]], exact match, case sensitive, generic erasure match, fine grain: none",
		searchPattern);
}

/**
 * Test TypeDeclarationPattern creation
 */
public void testSearchPatternCreation33() {
	IType localType = getCompilationUnit("/P/X.java").getType("X").getMethod("foo", new String[0]).getType("Y", 2);
	SearchPattern searchPattern = createPattern(
			localType,
			IJavaSearchConstants.DECLARATIONS);

	assertPattern(
		"TypeDeclarationPattern: pkg<>, enclosing<X.*>, type<Y>, exact match, case sensitive, generic erasure match, fine grain: none",
		searchPattern);
}

/**
 * Test TypeReferencePattern creation
 */
public void testSearchPatternCreation34() {
	IType localType = getCompilationUnit("/P/X.java").getType("X").getMethod("foo", new String[0]).getType("Y", 3);
	SearchPattern searchPattern = createPattern(
			localType,
			IJavaSearchConstants.REFERENCES);

	assertPattern(
		"TypeReferencePattern: qualification<X.*>, type<Y>, exact match, case sensitive, generic erasure match, fine grain: none",
		searchPattern);
}

/**
 * Test TypeDeclarationPattern creation
 */
public void testSearchPatternCreation35() {
	IType localType = getCompilationUnit("/P/X.java").getType("X").getInitializer(1).getType("Y", 2);
	SearchPattern searchPattern = createPattern(
			localType,
			IJavaSearchConstants.DECLARATIONS);

	assertPattern(
		"TypeDeclarationPattern: pkg<>, enclosing<X.*>, type<Y>, exact match, case sensitive, generic erasure match, fine grain: none",
		searchPattern);
}

/**
 * Test TypeReferencePattern creation
 */
public void testSearchPatternCreation36() {
	IType localType = getCompilationUnit("/P/X.java").getType("X").getInitializer(2).getType("Y", 3);
	SearchPattern searchPattern = createPattern(
			localType,
			IJavaSearchConstants.REFERENCES);

	assertPattern(
		"TypeReferencePattern: qualification<X.*>, type<Y>, exact match, case sensitive, generic erasure match, fine grain: none",
		searchPattern);
}

/**
 * Fine grain patterns
 */
public void testSearchPatternCreation37() {
	int allFlags = 0xFFFFFFF0;
	SearchPattern searchPattern = createPattern("*", TYPE, allFlags, true);
	assertPattern(
		"TypeReferencePattern: qualification<*>, type<*>, pattern match, case sensitive, generic full match, " +
		"fine grain: FIELD_DECLARATION_TYPE_REFERENCE | " +
		"LOCAL_VARIABLE_DECLARATION_TYPE_REFERENCE | " +
		"PARAMETER_DECLARATION_TYPE_REFERENCE | " +
		"SUPERTYPE_TYPE_REFERENCE | " +
		"THROWS_CLAUSE_TYPE_REFERENCE | " +
		"CAST_TYPE_REFERENCE | " +
		"CATCH_TYPE_REFERENCE | " +
		"CLASS_INSTANCE_CREATION_TYPE_REFERENCE | " +
		"RETURN_TYPE_REFERENCE | " +
		"IMPORT_DECLARATION_TYPE_REFERENCE | " +
		"ANNOTATION_TYPE_REFERENCE | " +
		"TYPE_ARGUMENT_TYPE_REFERENCE | " +
		"TYPE_VARIABLE_BOUND_TYPE_REFERENCE | " +
		"WILDCARD_BOUND_TYPE_REFERENCE | " +
		" | " + // unused slots
		" | " +
		" | " +
		" | " +
		"SUPER_REFERENCE | " +
		"QUALIFIED_REFERENCE | " +
		"THIS_REFERENCE | " +
		"IMPLICIT_THIS_REFERENCE | " +
		"METHOD_REFERENCE_EXPRESSION | " +
		"PERMITTYPE_TYPE_REFERENCE | " + // unused slots
		" | ",
		searchPattern);
}

/**
 * Test pattern  validation
 */
public void testSearchPatternValidMatchRule01() {
	assertValidMatchRule("foo",
		SearchPattern.R_EXACT_MATCH,
		SearchPattern.R_EXACT_MATCH);
}
public void testSearchPatternValidMatchRule02() {
	assertValidMatchRule("foo",
		SearchPattern.R_PREFIX_MATCH,
		SearchPattern.R_PREFIX_MATCH);
}
public void testSearchPatternValidMatchRule03() {
	assertValidMatchRule("foo",
		SearchPattern.R_PATTERN_MATCH,
		SearchPattern.R_EXACT_MATCH);
}
public void testSearchPatternValidMatchRule04() {
	assertValidMatchRule("foo",
		SearchPattern.R_PATTERN_MATCH | SearchPattern.R_PREFIX_MATCH,
		SearchPattern.R_PREFIX_MATCH);
}
public void testSearchPatternValidMatchRule05() {
	assertValidMatchRule("foo",
		SearchPattern.R_CAMELCASE_MATCH,
		SearchPattern.R_PREFIX_MATCH);
}
public void testSearchPatternValidMatchRule06() {
	assertValidMatchRule("foo",
		SearchPattern.R_CAMELCASE_SAME_PART_COUNT_MATCH,
		SearchPattern.R_EXACT_MATCH);
}
public void testSearchPatternValidMatchRule10() {
	assertValidMatchRule("CP*P",
		SearchPattern.R_EXACT_MATCH,
		SearchPattern.R_PATTERN_MATCH);
}
public void testSearchPatternValidMatchRule11() {
	assertValidMatchRule("CP*P",
		SearchPattern.R_PREFIX_MATCH,
		SearchPattern.R_PATTERN_MATCH);
}
public void testSearchPatternValidMatchRule12() {
	assertValidMatchRule("CP*P",
		SearchPattern.R_PATTERN_MATCH,
		SearchPattern.R_PATTERN_MATCH);
}
public void testSearchPatternValidMatchRule13() {
	assertValidMatchRule("CP*P",
		SearchPattern.R_PATTERN_MATCH | SearchPattern.R_PREFIX_MATCH,
		SearchPattern.R_PATTERN_MATCH);
}
public void testSearchPatternValidMatchRule14() {
	assertValidMatchRule("CP*P",
		SearchPattern.R_CAMELCASE_MATCH,
		SearchPattern.R_PATTERN_MATCH);
}
public void testSearchPatternValidMatchRule15() {
	assertValidMatchRule("CP*P",
		SearchPattern.R_CAMELCASE_SAME_PART_COUNT_MATCH,
		SearchPattern.R_PATTERN_MATCH);
}
public void testSearchPatternValidMatchRule20() {
	assertValidMatchRule("NPE",
		SearchPattern.R_CAMELCASE_MATCH);
}
public void testSearchPatternValidMatchRule21() {
	assertValidMatchRule("NPE",
		SearchPattern.R_CAMELCASE_MATCH | SearchPattern.R_PREFIX_MATCH | SearchPattern.R_CASE_SENSITIVE,
		SearchPattern.R_CAMELCASE_MATCH | SearchPattern.R_CASE_SENSITIVE);
}
public void testSearchPatternValidMatchRule22() {
	assertValidMatchRule("nPE",
		SearchPattern.R_CAMELCASE_MATCH);
}
public void testSearchPatternValidMatchRule23() {
	assertValidMatchRule("NuPoEx",
		SearchPattern.R_CAMELCASE_MATCH);
}
public void testSearchPatternValidMatchRule24() {
	assertValidMatchRule("oF",
		SearchPattern.R_CAMELCASE_MATCH);
}
public void testSearchPatternValidMatchRule30() {
	assertValidMatchRule("NPE",
		SearchPattern.R_CAMELCASE_SAME_PART_COUNT_MATCH);
}
public void testSearchPatternValidMatchRule31() {
	assertValidMatchRule("NPE",
		SearchPattern.R_CAMELCASE_SAME_PART_COUNT_MATCH | SearchPattern.R_PREFIX_MATCH,
		SearchPattern.R_CAMELCASE_SAME_PART_COUNT_MATCH);
}
public void testSearchPatternValidMatchRule32() {
	assertValidMatchRule("NPE",
		SearchPattern.R_CAMELCASE_SAME_PART_COUNT_MATCH | SearchPattern.R_CASE_SENSITIVE);
}
public void testSearchPatternValidMatchRule33() {
	assertValidMatchRule("NPE",
		SearchPattern.R_CAMELCASE_SAME_PART_COUNT_MATCH | SearchPattern.R_PREFIX_MATCH | SearchPattern.R_CASE_SENSITIVE,
		SearchPattern.R_CAMELCASE_SAME_PART_COUNT_MATCH | SearchPattern.R_CASE_SENSITIVE);
}
public void testSearchPatternValidMatchRule34() {
	assertValidMatchRule("nPE",
		SearchPattern.R_CAMELCASE_SAME_PART_COUNT_MATCH);
}
public void testSearchPatternValidMatchRule35() {
	assertValidMatchRule("NuPoEx",
		SearchPattern.R_CAMELCASE_SAME_PART_COUNT_MATCH);
}
public void testSearchPatternValidMatchRule36() {
	assertValidMatchRule("oF",
		SearchPattern.R_CAMELCASE_SAME_PART_COUNT_MATCH);
}
public void testSearchPatternValidMatchRule40() {
	assertValidMatchRule("Nu/Po/Ex",
		SearchPattern.R_CAMELCASE_MATCH,
		SearchPattern.R_PREFIX_MATCH);
}
public void testSearchPatternValidMatchRule41() {
	assertValidMatchRule("Nu.Po.Ex",
		SearchPattern.R_CAMELCASE_MATCH | SearchPattern.R_PREFIX_MATCH,
		SearchPattern.R_PREFIX_MATCH);
}
public void testSearchPatternValidMatchRule42() {
	assertValidMatchRule("hashMap",
		SearchPattern.R_CAMELCASE_MATCH);
}
public void testSearchPatternValidMatchRule43() {
	assertValidMatchRule("Hashmap",
		SearchPattern.R_CAMELCASE_MATCH,
		SearchPattern.R_PREFIX_MATCH);
}
public void testSearchPatternValidMatchRule44() {
	assertValidMatchRule("Nu/Po/Ex",
		SearchPattern.R_CAMELCASE_SAME_PART_COUNT_MATCH,
		SearchPattern.R_EXACT_MATCH);
}
public void testSearchPatternValidMatchRule45() {
	assertValidMatchRule("Nu.Po.Ex",
		SearchPattern.R_CAMELCASE_SAME_PART_COUNT_MATCH | SearchPattern.R_PREFIX_MATCH,
		SearchPattern.R_EXACT_MATCH);
}
public void testSearchPatternValidMatchRule46() {
	assertValidMatchRule("hashMap",
		SearchPattern.R_CAMELCASE_SAME_PART_COUNT_MATCH);
}
public void testSearchPatternValidMatchRule47() {
	assertValidMatchRule("Hashmap",
		SearchPattern.R_CAMELCASE_SAME_PART_COUNT_MATCH,
		SearchPattern.R_EXACT_MATCH);
}
}
