Bug 386410: [override method] JAX RS interface annotations are duplicated in the implementing class

comment 10
diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/codemanipulation/StubUtility2.java b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/codemanipulation/StubUtility2.java
index 441209e..e550cb7 100644
--- a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/codemanipulation/StubUtility2.java
+++ b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/codemanipulation/StubUtility2.java
@@ -890,8 +890,6 @@
 		if (JavaCore.ENABLED.equals(project.getOption(JavaCore.COMPILER_INHERIT_NULL_ANNOTATIONS, true)))
 			return false;
 		
-		String qualifiedName= annotationType.getQualifiedName();
-		return qualifiedName.equals(project.getOption(JavaCore.COMPILER_NONNULL_ANNOTATION_NAME, true))
-				|| qualifiedName.equals(project.getOption(JavaCore.COMPILER_NULLABLE_ANNOTATION_NAME, true));
+		return Bindings.isNullAnnotation(annotationType, project);
 	}
 }
diff --git a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/dom/Bindings.java b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/dom/Bindings.java
index 6f6bca6..bd2bcc0 100644
--- a/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/dom/Bindings.java
+++ b/org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/dom/Bindings.java
@@ -26,6 +26,7 @@
 import org.eclipse.jdt.core.IJavaProject;
 import org.eclipse.jdt.core.IMethod;
 import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaCore;
 import org.eclipse.jdt.core.JavaModelException;
 import org.eclipse.jdt.core.Signature;
 import org.eclipse.jdt.core.dom.AST;
@@ -1425,4 +1426,10 @@
 		}
 	}
 
+	public static boolean isNullAnnotation(ITypeBinding annotationType, IJavaProject project) {
+		String qualifiedName= annotationType.getQualifiedName();
+		return qualifiedName.equals(project.getOption(JavaCore.COMPILER_NONNULL_ANNOTATION_NAME, true))
+				|| qualifiedName.equals(project.getOption(JavaCore.COMPILER_NULLABLE_ANNOTATION_NAME, true));
+	}
+
 }
diff --git a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/ExtractInterfaceProcessor.java b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/ExtractInterfaceProcessor.java
index cd3e30c..4aee33c 100644
--- a/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/ExtractInterfaceProcessor.java
+++ b/org.eclipse.jdt.ui/core refactoring/org/eclipse/jdt/internal/corext/refactoring/structure/ExtractInterfaceProcessor.java
@@ -93,7 +93,6 @@
 import org.eclipse.jdt.internal.core.refactoring.descriptors.RefactoringSignatureDescriptorFactory;
 import org.eclipse.jdt.internal.corext.codemanipulation.CodeGenerationSettings;
 import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility;
-import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility2;
 import org.eclipse.jdt.internal.corext.dom.Bindings;
 import org.eclipse.jdt.internal.corext.dom.ModifierRewrite;
 import org.eclipse.jdt.internal.corext.refactoring.Checks;
@@ -432,7 +431,7 @@
 				final Set<String> replacements= new HashSet<String>();
 				if (fReplace)
 					rewriteTypeOccurrences(manager, sourceRewrite, copy, replacements, status, new SubProgressMonitor(monitor, 220));
-				createMethodComments(sourceRewrite, replacements);
+				rewriteSourceMethods(sourceRewrite, replacements);
 				manager.manage(fSubType.getCompilationUnit(), sourceRewrite.createChange(true));
 			}
 			return manager;
@@ -584,8 +583,8 @@
 	}
 
 	/**
-	 * Creates the method annotations and comments of the extracted methods in
-	 * the source type.
+	 * Rewrites the extracted methods in the source type.
+	 * Adds/removes method annotations and adds method comments.
 	 *
 	 * @param sourceRewrite
 	 *            the source compilation unit rewrite
@@ -595,18 +594,43 @@
 	 * @throws CoreException
 	 *             if an error occurs
 	 */
-	protected final void createMethodComments(final CompilationUnitRewrite sourceRewrite, final Set<String> replacements) throws CoreException {
+	private void rewriteSourceMethods(final CompilationUnitRewrite sourceRewrite, final Set<String> replacements) throws CoreException {
 		Assert.isNotNull(sourceRewrite);
 		Assert.isNotNull(replacements);
-		if (fMembers.length > 0 && (fAnnotations || fComments)) {
+		if (fMembers.length > 0) {
 			IJavaProject project= fSubType.getJavaProject();
 			boolean annotations= fAnnotations && !JavaModelUtil.isVersionLessThan(project.getOption(JavaCore.COMPILER_SOURCE, true), JavaCore.VERSION_1_6);
+			boolean inheritNullAnnotations= JavaCore.ENABLED.equals(project.getOption(JavaCore.COMPILER_INHERIT_NULL_ANNOTATIONS, true));
 			boolean javadoc= project.getOption(JavaCore.COMPILER_DOC_COMMENT_SUPPORT, true).equals(JavaCore.ENABLED);
 			IMember member= null;
 			for (int index= 0; index < fMembers.length; index++) {
 				member= fMembers[index];
 				if (member instanceof IMethod) {
 					MethodDeclaration declaration= ASTNodeSearchUtil.getMethodDeclarationNode((IMethod) member, sourceRewrite.getRoot());
+					if (inheritNullAnnotations) {
+						for (IExtendedModifier extended : (List<IExtendedModifier>) declaration.modifiers()) {
+							if (extended.isAnnotation()) {
+								Annotation annotation= (Annotation) extended;
+								ITypeBinding binding= annotation.resolveTypeBinding();
+								if (binding != null && Bindings.isNullAnnotation(binding, project)) {
+									ASTRewrite rewrite= sourceRewrite.getASTRewrite();
+									rewrite.getListRewrite(declaration, MethodDeclaration.MODIFIERS2_PROPERTY).remove(annotation, null);
+								}
+							}
+						}
+						for (SingleVariableDeclaration parameter : (List<SingleVariableDeclaration>) declaration.parameters()) {
+							for (IExtendedModifier extended : (List<IExtendedModifier>) parameter.modifiers()) {
+								if (extended.isAnnotation()) {
+									Annotation annotation= (Annotation) extended;
+									ITypeBinding binding= annotation.resolveTypeBinding();
+									if (binding != null && Bindings.isNullAnnotation(binding, project)) {
+										ASTRewrite rewrite= sourceRewrite.getASTRewrite();
+										rewrite.getListRewrite(parameter, SingleVariableDeclaration.MODIFIERS2_PROPERTY).remove(annotation, null);
+									}
+								}
+							}
+						}
+					}
 					if (annotations) {
 						ASTRewrite rewrite= sourceRewrite.getASTRewrite();
 						AST ast= rewrite.getAST();
@@ -665,7 +689,7 @@
 			} else if (extended.isAnnotation()) {
 				annotation= (Annotation) extended;
 				ITypeBinding binding= annotation.resolveTypeBinding();
-				if (binding.getQualifiedName().equals("java.lang.Override") || ! StubUtility2.isCopyOnInheritAnnotation(binding, sourceProject)) //$NON-NLS-1$
+				if (binding != null && binding.getQualifiedName().equals("java.lang.Override") || ! Bindings.isNullAnnotation(binding, sourceProject)) //$NON-NLS-1$
 					list.remove(annotation, null);
 			}
 		}
@@ -684,7 +708,7 @@
 				} else if (extended.isAnnotation()) {
 					annotation= (Annotation) extended;
 					ITypeBinding binding= annotation.resolveTypeBinding();
-					if (! StubUtility2.isCopyOnInheritAnnotation(binding, sourceProject))
+					if (binding != null && ! Bindings.isNullAnnotation(binding, sourceProject))
 						modifierRewrite.remove(annotation, null);
 				}
 			}