Fix for Bug 521240: Search ignores the qualifier of the parameter type
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java
index 98a256d..fe79f9f 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchBugsTests.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2015 IBM Corporation and others.
+ * Copyright (c) 2000, 2017 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
@@ -15102,4 +15102,38 @@
 	assertTrue("Unexpected Method Name", expectedName.equals(name));
 	assertTrue("IJavaElement Does not exist", method.exists());
 }
+public void testBug521240_001() throws CoreException {
+	this.workingCopies = new ICompilationUnit[3];
+	WorkingCopyOwner owner = new WorkingCopyOwner() {};
+	this.workingCopies[0] = getWorkingCopy("/JavaSearchBugs/src/pack1/X.java",
+		"package pack1;\n" +
+		"public class X {\n" +
+		"    void foo(Y s) {}\n" +
+		"    void foo(pack2.Y s) {}\n" +
+		"}\n",
+		owner
+	);
+	this.workingCopies[1] = getWorkingCopy("/JavaSearchBugs/src/pack1/Y.java",
+			"package pack1;\n" +
+			"public class Y{}\n",
+			owner
+		);
+	this.workingCopies[2] = getWorkingCopy("/JavaSearchBugs/src/pack2/Y.java",
+		"package pack2;\n" +
+		"public class Y{}\n",
+		owner
+	);
+	SearchPattern pattern = SearchPattern.createPattern("pack1.X.foo(pack1.Y)",METHOD, DECLARATIONS,
+			SearchPattern.R_ERASURE_MATCH | SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE);
+
+	new SearchEngine(this.workingCopies).search(pattern,
+			new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()},
+			getJavaSearchWorkingCopiesScope(),
+			this.resultCollector,
+			null);
+	assertSearchResults(
+			"src/pack1/X.java void pack1.X.foo(Y) [foo] EXACT_MATCH"
+	);
+}
+
 }
\ No newline at end of file
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java
index 99e193f..3d4d143 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2016 IBM Corporation and others.
+ * Copyright (c) 2000, 2017 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
@@ -1105,6 +1105,13 @@
 	this.bindings.put(methodPattern, result != null ? result : new ProblemMethodBinding(methodPattern.selector, null, ProblemReasons.NotFound));
 	return result;
 }
+private boolean matchParams(MethodPattern methodPattern, int index, TypeBinding binding) {
+	char[] qualifier = CharOperation.concat(methodPattern.parameterQualifications[index], methodPattern.parameterSimpleNames[index], '.');
+	int offset = (qualifier.length > 0 && qualifier[0] == '*') ? 1 : 0;
+	String s1 = new String(qualifier, offset, qualifier.length - offset);
+	char[] s2 = CharOperation.concat(binding.qualifiedPackageName(), binding.qualifiedSourceName(), '.');
+	return new String(s2).endsWith(s1);
+}
 
 private MethodBinding getMethodBinding(MethodPattern methodPattern, TypeBinding declaringTypeBinding) {
 	MethodBinding result;
@@ -1125,7 +1132,8 @@
 		boolean found = false;
 		if (methodParameters != null && paramLength == paramTypeslength) {
 			for (int p=0; p<paramLength; p++) {
-				if (CharOperation.equals(methodParameters[p].sourceName(), parameterTypes[p])) {
+				TypeBinding parameter = methodParameters[p];
+				if (matchParams(methodPattern, p, parameter)) {
 					// param erasure match
 					found = true;
 				} else {