Fixed bug 395228: [introduce indirection] Adds unneccessary import when
inner class is used as parameter in surrounding class

Change-Id: Ibcf418fdb50c214628c6f83cfd21a8d1f338b71c
Signed-off-by: Nikolay Metchev <nikolaymetchev@gmail.com>
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceIndirection/test37/in/Test.java b/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceIndirection/test37/in/Test.java
new file mode 100644
index 0000000..3bea7ad
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceIndirection/test37/in/Test.java
@@ -0,0 +1,9 @@
+package p;
+
+class Test {
+    void foo(C c) {
+    }
+
+    private class C {
+    }
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceIndirection/test37/out/Test.java b/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceIndirection/test37/out/Test.java
new file mode 100644
index 0000000..15a9de8
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceIndirection/test37/out/Test.java
@@ -0,0 +1,17 @@
+package p;
+
+class Test {
+    /**
+	 * @param test
+	 * @param c
+	 */
+	public static void foo(Test test, C c) {
+		test.foo(c);
+	}
+
+	void foo(C c) {
+    }
+
+    private class C {
+    }
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceIndirection/test38/in/Test.java b/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceIndirection/test38/in/Test.java
new file mode 100644
index 0000000..01afbc7
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceIndirection/test38/in/Test.java
@@ -0,0 +1,13 @@
+package p;
+
+class Test {
+	static class C {
+		static void foo() {
+			Object o= C.class;
+		}
+	}
+
+	void f() {
+		C.foo();
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceIndirection/test38/out/Test.java b/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceIndirection/test38/out/Test.java
new file mode 100644
index 0000000..e4010ed
--- /dev/null
+++ b/org.eclipse.jdt.ui.tests.refactoring/resources/IntroduceIndirection/test38/out/Test.java
@@ -0,0 +1,20 @@
+package p;
+
+class Test {
+	static class C {
+		static void foo() {
+			Object o= C.class;
+		}
+
+		/**
+		 * 
+		 */
+		public static void foo2() {
+			C.foo();
+		}
+	}
+
+	void f() {
+		C.foo2();
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/IntroduceIndirectionTests.java b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/IntroduceIndirectionTests.java
index 855a08a..53a85fd 100644
--- a/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/IntroduceIndirectionTests.java
+++ b/org.eclipse.jdt.ui.tests.refactoring/test cases/org/eclipse/jdt/ui/tests/refactoring/IntroduceIndirectionTests.java
@@ -8,6 +8,7 @@
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Nikolay Metchev <nikolaymetchev@gmail.com> - [introduce indirection] ClassCastException when introducing indirection on method in generic class - https://bugs.eclipse.org/395231
+ *     Nikolay Metchev <nikolaymetchev@gmail.com> - [introduce indirection] Adds unneccessary import when inner class is used as parameter in surrounding class - https://bugs.eclipse.org/395228
  *******************************************************************************/
 package org.eclipse.jdt.ui.tests.refactoring;
 
@@ -332,4 +333,14 @@
 		// test for bug 395231
 		helperPass(new String[] { "p.Test" }, "foo", "p.Test0", 6, 9, 6, 13);
 	}
+
+	public void test37() throws Exception {
+		// test for bug 127665
+		helperPass(new String[] { "p.Test" }, "foo", "p.Test0", 4, 10, 4, 13);
+	}
+
+	public void test38() throws Exception {
+		// test for bug 127665
+		helperPass(new String[] { "p.Test" }, "foo2", "p.Test0", 5, 21, 5, 24);
+	}
 }
diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/IntroduceIndirectionRefactoring.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/IntroduceIndirectionRefactoring.java
index 9121600..5fb7843 100644
--- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/IntroduceIndirectionRefactoring.java
+++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/code/IntroduceIndirectionRefactoring.java
@@ -8,6 +8,7 @@
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Nikolay Metchev <nikolaymetchev@gmail.com> - [introduce indirection] ClassCastException when introducing indirection on method in generic class - https://bugs.eclipse.org/395231
+ *     Nikolay Metchev <nikolaymetchev@gmail.com> - [introduce indirection] Adds unneccessary import when inner class is used as parameter in surrounding class - https://bugs.eclipse.org/395228
  *******************************************************************************/
 package org.eclipse.jdt.internal.corext.refactoring.code;
 
@@ -829,20 +830,20 @@
 			intermediary.parameters().add(parameter);
 		}
 		// Add other params
-		copyArguments(intermediary, imRewrite);
+		copyArguments(intermediary, imRewrite, context);
 
 		// Add type parameters of declaring type (and enclosing types)
 		if (!isStaticTarget() && fIntermediaryFirstParameterType.isGenericType())
-			addTypeParameters(imRewrite, intermediary.typeParameters(), fIntermediaryFirstParameterType);
+			addTypeParameters(imRewrite, intermediary.typeParameters(), fIntermediaryFirstParameterType, context);
 
 		// Add type params of method
-		copyTypeParameters(intermediary, imRewrite);
+		copyTypeParameters(intermediary, imRewrite, context);
 
 		// Return type
 		intermediary.setReturnType2(imRewrite.getImportRewrite().addImport(fTargetMethodBinding.getReturnType(), ast, context));
 
 		// Exceptions
-		copyExceptions(intermediary, imRewrite);
+		copyExceptions(intermediary, imRewrite, context);
 
 		// Body
 		MethodInvocation invocation= imRewrite.getAST().newMethodInvocation();
@@ -878,11 +879,11 @@
 				.createGroupDescription(RefactoringCoreMessages.IntroduceIndirectionRefactoring_group_description_create_new_method));
 	}
 
-	private void addTypeParameters(CompilationUnitRewrite imRewrite, List<TypeParameter> list, ITypeBinding parent) {
+	private void addTypeParameters(CompilationUnitRewrite imRewrite, List<TypeParameter> list, ITypeBinding parent, ImportRewriteContext context) {
 
 		ITypeBinding enclosing= parent.getDeclaringClass();
 		if (enclosing != null)
-			addTypeParameters(imRewrite, list, enclosing);
+			addTypeParameters(imRewrite, list, enclosing, context);
 
 		ITypeBinding[] typeParameters= parent.getTypeParameters();
 		for (int i= 0; i < typeParameters.length; i++) {
@@ -891,7 +892,7 @@
 			ITypeBinding[] bounds= typeParameters[i].getTypeBounds();
 			for (int j= 0; j < bounds.length; j++)
 				if (!"java.lang.Object".equals(bounds[j].getQualifiedName())) //$NON-NLS-1$
-					ntp.typeBounds().add(imRewrite.getImportRewrite().addImport(bounds[j], imRewrite.getAST()));
+					ntp.typeBounds().add(imRewrite.getImportRewrite().addImport(bounds[j], imRewrite.getAST(), context));
 			list.add(ntp);
 		}
 	}
@@ -913,7 +914,7 @@
 			invocation.arguments().add(ast.newSimpleName(names[i]));
 	}
 
-	private void copyArguments(MethodDeclaration intermediary, CompilationUnitRewrite rew) throws JavaModelException {
+	private void copyArguments(MethodDeclaration intermediary, CompilationUnitRewrite rew, ImportRewriteContext context) throws JavaModelException {
 		String[] names= fTargetMethod.getParameterNames();
 		ITypeBinding[] types= fTargetMethodBinding.getParameterTypes();
 		for (int i= 0; i < names.length; i++) {
@@ -927,12 +928,12 @@
 					typeBinding= typeBinding.getComponentType();
 			}
 
-			newElement.setType(rew.getImportRewrite().addImport(typeBinding, rew.getAST()));
+			newElement.setType(rew.getImportRewrite().addImport(typeBinding, rew.getAST(), context));
 			intermediary.parameters().add(newElement);
 		}
 	}
 
-	private void copyTypeParameters(MethodDeclaration intermediary, CompilationUnitRewrite rew) {
+	private void copyTypeParameters(MethodDeclaration intermediary, CompilationUnitRewrite rew,  ImportRewriteContext context) {
 		ITypeBinding[] typeParameters= fTargetMethodBinding.getTypeParameters();
 		for (int i= 0; i < typeParameters.length; i++) {
 			ITypeBinding current= typeParameters[i];
@@ -942,16 +943,16 @@
 			ITypeBinding[] bounds= current.getTypeBounds();
 			for (int j= 0; j < bounds.length; j++)
 				if (!"java.lang.Object".equals(bounds[j].getQualifiedName())) //$NON-NLS-1$
-					parameter.typeBounds().add(rew.getImportRewrite().addImport(bounds[j], rew.getAST()));
+					parameter.typeBounds().add(rew.getImportRewrite().addImport(bounds[j], rew.getAST(), context));
 
 			intermediary.typeParameters().add(parameter);
 		}
 	}
 
-	private void copyExceptions(MethodDeclaration intermediary, CompilationUnitRewrite imRewrite) {
+	private void copyExceptions(MethodDeclaration intermediary, CompilationUnitRewrite imRewrite,  ImportRewriteContext context) {
 		ITypeBinding[] exceptionTypes= fTargetMethodBinding.getExceptionTypes();
 		for (int i= 0; i < exceptionTypes.length; i++) {
-			Type exceptionType= imRewrite.getImportRewrite().addImport(exceptionTypes[i], imRewrite.getAST());
+			Type exceptionType= imRewrite.getImportRewrite().addImport(exceptionTypes[i], imRewrite.getAST(), context);
 			intermediary.thrownExceptionTypes().add(exceptionType);
 		}
 	}
@@ -971,8 +972,9 @@
 		List<Expression> newInvocationArgs= newInvocation.arguments();
 		List<Expression> originalInvocationArgs= originalInvocation.arguments();
 
+		ContextSensitiveImportRewriteContext context= new ContextSensitiveImportRewriteContext(originalInvocation, unitRewriter.getImportRewrite());
 		// static call => always use a qualifier
-		String qualifier= unitRewriter.getImportRewrite().addImport(fIntermediaryTypeBinding);
+		String qualifier= unitRewriter.getImportRewrite().addImport(fIntermediaryTypeBinding, context);
 		newInvocation.setExpression(ASTNodeFactory.newName(unitRewriter.getAST(), qualifier));
 		newInvocation.setName(unitRewriter.getAST().newSimpleName(getIntermediaryMethodName()));