Quickfix improvements:
- support changing signature of target method in message send
- support changing signature in other CU
- handle existing parameter annotations 
  - in multi mode don't change them
  - in single mode replace
  - never duplicate the same annotation

diff --git a/plugins/org.eclipse.objectteams.jdt.nullity/src/org/eclipse/objectteams/internal/jdt/nullity/quickfix/FixMessages.java b/plugins/org.eclipse.objectteams.jdt.nullity/src/org/eclipse/objectteams/internal/jdt/nullity/quickfix/FixMessages.java
index e330dd8..f055c61 100644
--- a/plugins/org.eclipse.objectteams.jdt.nullity/src/org/eclipse/objectteams/internal/jdt/nullity/quickfix/FixMessages.java
+++ b/plugins/org.eclipse.objectteams.jdt.nullity/src/org/eclipse/objectteams/internal/jdt/nullity/quickfix/FixMessages.java
@@ -15,12 +15,15 @@
 public class FixMessages extends NLS {
 	private static final String BUNDLE_NAME = "org.eclipse.objectteams.internal.jdt.nullity.quickfix.FixMessages"; //$NON-NLS-1$
 	
-	public static String Generic_add_missing_annotation;
 	
 	public static String NullAnnotationsCleanUp_add_nullable_annotation;
 	
 	public static String QuickFixes_add_annotation_change_name;
 	
+	public static String QuickFixes_declare_method_parameter_nullable;
+
+	public static String QuickFixes_declare_method_return_nullable;
+
 	static {
 		// initialize resource bundle
 		NLS.initializeMessages(BUNDLE_NAME, FixMessages.class);
diff --git a/plugins/org.eclipse.objectteams.jdt.nullity/src/org/eclipse/objectteams/internal/jdt/nullity/quickfix/FixMessages.properties b/plugins/org.eclipse.objectteams.jdt.nullity/src/org/eclipse/objectteams/internal/jdt/nullity/quickfix/FixMessages.properties
index 67ed215..985ec90 100644
--- a/plugins/org.eclipse.objectteams.jdt.nullity/src/org/eclipse/objectteams/internal/jdt/nullity/quickfix/FixMessages.properties
+++ b/plugins/org.eclipse.objectteams.jdt.nullity/src/org/eclipse/objectteams/internal/jdt/nullity/quickfix/FixMessages.properties
@@ -1,3 +1,4 @@
-Generic_add_missing_annotation=Add missing @{0} annotation
 NullAnnotationsCleanUp_add_nullable_annotation=Add missing @Nullable annotation
 QuickFixes_add_annotation_change_name=Add Annotations
+QuickFixes_declare_method_parameter_nullable=Declare method parameter as @{0}
+QuickFixes_declare_method_return_nullable=Declare method return as @{0}
diff --git a/plugins/org.eclipse.objectteams.jdt.nullity/src/org/eclipse/objectteams/internal/jdt/nullity/quickfix/QuickFixes.java b/plugins/org.eclipse.objectteams.jdt.nullity/src/org/eclipse/objectteams/internal/jdt/nullity/quickfix/QuickFixes.java
index 9a377f5..d6e21a3 100644
--- a/plugins/org.eclipse.objectteams.jdt.nullity/src/org/eclipse/objectteams/internal/jdt/nullity/quickfix/QuickFixes.java
+++ b/plugins/org.eclipse.objectteams.jdt.nullity/src/org/eclipse/objectteams/internal/jdt/nullity/quickfix/QuickFixes.java
@@ -20,7 +20,6 @@
 import java.util.Map;
 import java.util.Set;
 
-import org.eclipse.core.runtime.CoreException;
 import org.eclipse.jdt.core.IAnnotation;
 import org.eclipse.jdt.core.ICompilationUnit;
 import org.eclipse.jdt.core.IJavaElement;
@@ -28,11 +27,13 @@
 import org.eclipse.jdt.core.JavaModelException;
 import org.eclipse.jdt.core.compiler.IProblem;
 import org.eclipse.jdt.core.dom.ASTNode;
-import org.eclipse.jdt.core.dom.BodyDeclaration;
 import org.eclipse.jdt.core.dom.CompilationUnit;
 import org.eclipse.jdt.core.dom.IBinding;
+import org.eclipse.jdt.core.dom.IMethodBinding;
+import org.eclipse.jdt.core.dom.ITypeBinding;
 import org.eclipse.jdt.core.dom.IVariableBinding;
 import org.eclipse.jdt.core.dom.MethodDeclaration;
+import org.eclipse.jdt.core.dom.MethodInvocation;
 import org.eclipse.jdt.core.dom.SimpleName;
 import org.eclipse.jdt.internal.corext.dom.ASTNodes;
 import org.eclipse.jdt.internal.corext.fix.CompilationUnitRewriteOperationsFix;
@@ -41,6 +42,7 @@
 import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
 import org.eclipse.jdt.internal.corext.util.Messages;
 import org.eclipse.jdt.internal.ui.JavaPluginImages;
+import org.eclipse.jdt.internal.ui.text.correction.ASTResolving;
 import org.eclipse.jdt.internal.ui.text.correction.ProblemLocation;
 import org.eclipse.jdt.internal.ui.text.correction.proposals.FixCorrectionProposal;
 import org.eclipse.jdt.ui.cleanup.CleanUpOptions;
@@ -70,6 +72,8 @@
 			switch (problemId) {
 			case DefiniteNullFromNonNullMethod:
 			case PotentialNullFromNonNullMethod:
+			case DefiniteNullToNonNullParameter:
+			case PotentialNullToNonNullParameter:
 			case IProblem.NonNullLocalVariableComparisonYieldsFalse:
 			case IProblem.RedundantNullCheckOnNonNullLocalVariable:
 					return true;
@@ -91,6 +95,8 @@
 			switch (id) {
 			case DefiniteNullFromNonNullMethod:
 			case PotentialNullFromNonNullMethod:
+			case DefiniteNullToNonNullParameter:
+			case PotentialNullToNonNullParameter:
 				addNullableAnnotationInSignatureProposal(context, problem, proposals);
 				break;			
 			case IProblem.NonNullLocalVariableComparisonYieldsFalse:
@@ -116,6 +122,8 @@
 				options.put(CleanUpConstants.ADD_POTENTIALLY_MISSING_RETURN_ANNOTATION_NULLABLE, CleanUpOptions.TRUE);
 			if (mayIndicateParameterNullcheck(problem.getProblemId()))
 				options.put(CleanUpConstants.ADD_DEFINITELY_MISSING_PARAMETER_ANNOTATION_NULLABLE, CleanUpOptions.TRUE);
+			if (problem.getProblemId() == DefiniteNullToNonNullParameter)
+				options.put(CleanUpConstants.ADD_DEFINITELY_MISSING_PARAMETER_ANNOTATION_NULLABLE, CleanUpOptions.TRUE);
 			FixCorrectionProposal proposal= new FixCorrectionProposal(fix, new NullAnnotationsCleanUp(options, this), 15, image, context);
 			proposals.add(proposal);
 		}		
@@ -138,15 +146,30 @@
 
 	CompilationUnitRewriteOperationsFix createNullableInSignatureFix(CompilationUnit compilationUnit, IProblemLocation problem) {
 		String nullableAnnotationName = getNullableAnnotationName(compilationUnit.getJavaElement(), false);
-		CompilationUnitRewriteOperation operation = createAddNullableOperation(compilationUnit, problem, nullableAnnotationName, null);
+		String nonNullAnnotationName = getNonNullAnnotationName(compilationUnit.getJavaElement(), false);
+		RewriteOperations.SignatureAnnotationRewriteOperation operation = createAddNullableOperation(
+				compilationUnit, problem, nullableAnnotationName, nonNullAnnotationName, null, false, true);
 		if (operation == null)
 			return null;
 		
 		int lastDot = nullableAnnotationName.lastIndexOf('.');
 		if (lastDot != -1)
 			nullableAnnotationName = nullableAnnotationName.substring(lastDot+1);
-		return new CompilationUnitRewriteOperationsFix(Messages.format(FixMessages.Generic_add_missing_annotation, nullableAnnotationName),
-														compilationUnit, 
+		String messageTemplate = null;
+		switch (problem.getProblemId()) {
+		case DefiniteNullFromNonNullMethod:
+		case PotentialNullFromNonNullMethod:
+			messageTemplate = FixMessages.QuickFixes_declare_method_return_nullable;
+			break;
+		case DefiniteNullToNonNullParameter:
+		case PotentialNullToNonNullParameter:
+		case IProblem.NonNullLocalVariableComparisonYieldsFalse:
+		case IProblem.RedundantNullCheckOnNonNullLocalVariable:
+			messageTemplate = FixMessages.QuickFixes_declare_method_parameter_nullable;
+			break;
+		}
+		return new CompilationUnitRewriteOperationsFix(Messages.format(messageTemplate, nullableAnnotationName),
+														operation.getCompilationUnit(), 
 														new CompilationUnitRewriteOperation[] {operation});
 	}
 
@@ -189,18 +212,21 @@
 	@SuppressWarnings({ "rawtypes", "unchecked" })
 	void createAddNullableAnnotationOperations(CompilationUnit compilationUnit, IProblemLocation[] locations, List result) {
 		String nullableAnnotationName = getNullableAnnotationName(compilationUnit.getJavaElement(), false);
+		String nonNullAnnotationName = getNonNullAnnotationName(compilationUnit.getJavaElement(), false);
 		Set<String> handledPositions = new HashSet<String>();
 		for (int i= 0; i < locations.length; i++) {
 			IProblemLocation problem= locations[i];
 			if (problem == null) continue; // problem was filtered out by createCleanUp()
-			CompilationUnitRewriteOperation fix = createAddNullableOperation(compilationUnit, problem, nullableAnnotationName, handledPositions);
+			CompilationUnitRewriteOperation fix = createAddNullableOperation(
+						compilationUnit, problem, nullableAnnotationName, nonNullAnnotationName, handledPositions, true, false);
 			if (fix != null)
 				result.add(fix);
 		}
 	}
 	
-	CompilationUnitRewriteOperation createAddNullableOperation(CompilationUnit compilationUnit,
-			IProblemLocation problem, String nullableAnnotationName, Set<String> handledPositions) 
+	RewriteOperations.SignatureAnnotationRewriteOperation createAddNullableOperation(CompilationUnit compilationUnit,
+			IProblemLocation problem, String nullableAnnotationName, String nonNullAnnotationName, Set<String> handledPositions,
+			boolean thisUnitOnly, boolean allowRemove) 
 	{
 		ICompilationUnit cu= (ICompilationUnit)compilationUnit.getJavaElement();
 		if (!JavaModelUtil.is50OrHigher(cu.getJavaProject()))
@@ -216,23 +242,59 @@
 		if (selectedNode == null)
 			return null;
 			
-		ASTNode declaringNode= getDeclaringNode(selectedNode);
-		if (!(declaringNode instanceof MethodDeclaration))
-			return null;
-		
-		MethodDeclaration declaration= (MethodDeclaration) declaringNode;
-		
 		RewriteOperations.SignatureAnnotationRewriteOperation result = null;
-		if (mayIndicateParameterNullcheck(problem.getProblemId())) {
-			if (selectedNode.getNodeType() == ASTNode.SIMPLE_NAME && declaration.getNodeType() == ASTNode.METHOD_DECLARATION) {
-				IBinding binding = ((SimpleName)selectedNode).resolveBinding();
-				if (binding.getKind() == IBinding.VARIABLE && ((IVariableBinding)binding).isParameter())
-					result = new RewriteOperations.ParameterAnnotationRewriteOperation(declaration, nullableAnnotationName, ((SimpleName) selectedNode).getIdentifier());
+		ASTNode declaringNode= getDeclaringNode(selectedNode);
+		if (selectedNode.getParent() instanceof MethodInvocation) {
+			// check problem ID!
+			MethodInvocation methodInvocation = (MethodInvocation)selectedNode.getParent();
+			int paramIdx = methodInvocation.arguments().indexOf(selectedNode);
+			IMethodBinding methodBinding = methodInvocation.resolveMethodBinding();
+			ASTNode methodDecl= compilationUnit.findDeclaringNode(methodBinding.getMethodDeclaration());
+			if (methodDecl == null) {
+				// is methodDecl defined in another CU?
+				ITypeBinding declaringTypeDecl= methodBinding.getDeclaringClass().getTypeDeclaration();
+				if (declaringTypeDecl.isFromSource()) {
+					ICompilationUnit targetCU = null;
+					try {
+						targetCU = ASTResolving.findCompilationUnitForBinding(cu, compilationUnit, declaringTypeDecl);
+					} catch (JavaModelException e) { /* can't do better */ }
+					if (targetCU != null) {
+						compilationUnit = ASTResolving.createQuickFixAST(targetCU, null);
+						methodDecl= compilationUnit.findDeclaringNode(methodBinding.getKey());
+					}
+				}
 			}
-		} else {
-			result = new RewriteOperations.ReturnAnnotationRewriteOperation(declaration, nullableAnnotationName);
-		}
+			if (methodDecl != null)
+				result = new RewriteOperations.ParameterAnnotationRewriteOperation(compilationUnit,
+																				   (MethodDeclaration) methodDecl,
+																				   nullableAnnotationName,
+																				   nonNullAnnotationName,
+																				   paramIdx,
+																				   allowRemove);
+		} else if (declaringNode instanceof MethodDeclaration) {
 		
+			MethodDeclaration declaration= (MethodDeclaration) declaringNode;
+			
+			if (mayIndicateParameterNullcheck(problem.getProblemId())) {
+				if (selectedNode.getNodeType() == ASTNode.SIMPLE_NAME && declaration.getNodeType() == ASTNode.METHOD_DECLARATION) {
+					IBinding binding = ((SimpleName)selectedNode).resolveBinding();
+					if (binding.getKind() == IBinding.VARIABLE && ((IVariableBinding)binding).isParameter())
+						result = new RewriteOperations.ParameterAnnotationRewriteOperation(compilationUnit,
+																						   declaration,
+																						   nullableAnnotationName,
+																						   nonNullAnnotationName,
+																						   ((SimpleName) selectedNode).getIdentifier(),
+																						   allowRemove);
+				}
+			} else {
+				result = new RewriteOperations.ReturnAnnotationRewriteOperation(compilationUnit,
+																				declaration,
+																				nullableAnnotationName,
+																				nonNullAnnotationName,
+																				allowRemove);
+			}
+			
+		}
 		if (handledPositions != null && result != null) {
 			if (handledPositions.contains(result.getKey()))
 				return null;
@@ -248,6 +310,7 @@
 
 	static boolean isMissingNullableAnnotationProblem(int id) {
 		return id == DefiniteNullFromNonNullMethod || id == PotentialNullFromNonNullMethod 
+				|| id == DefiniteNullToNonNullParameter || id == PotentialNullToNonNullParameter
 				|| mayIndicateParameterNullcheck(id);
 	}
 	
@@ -274,16 +337,16 @@
 		return false;
 	}
 
-	static String getNullableAnnotationName(IJavaElement compilationUnit, boolean makeSimple) {
-		String qualifiedName = compilationUnit.getJavaProject().getOption(NullCompilerOptions.OPTION_NullableAnnotationName, true);
+	static String getNullableAnnotationName(IJavaElement javaElement, boolean makeSimple) {
+		String qualifiedName = javaElement.getJavaProject().getOption(NullCompilerOptions.OPTION_NullableAnnotationName, true);
 		int lastDot;
 		if (makeSimple && qualifiedName != null && (lastDot = qualifiedName.lastIndexOf('.')) != -1)
 			return qualifiedName.substring(lastDot+1);
 		return qualifiedName;
 	}
 
-	static String getNonNullAnnotationName(ICompilationUnit compilationUnit, boolean makeSimple) {
-		String qualifiedName = compilationUnit.getJavaProject().getOption(NullCompilerOptions.OPTION_NonNullAnnotationName, true);
+	static String getNonNullAnnotationName(IJavaElement javaElement, boolean makeSimple) {
+		String qualifiedName = javaElement.getJavaProject().getOption(NullCompilerOptions.OPTION_NonNullAnnotationName, true);
 		int lastDot;
 		if (makeSimple && qualifiedName != null && (lastDot = qualifiedName.lastIndexOf('.')) != -1)
 			return qualifiedName.substring(lastDot+1);
diff --git a/plugins/org.eclipse.objectteams.jdt.nullity/src/org/eclipse/objectteams/internal/jdt/nullity/quickfix/RewriteOperations.java b/plugins/org.eclipse.objectteams.jdt.nullity/src/org/eclipse/objectteams/internal/jdt/nullity/quickfix/RewriteOperations.java
index 69d6d25..01b20e2 100644
--- a/plugins/org.eclipse.objectteams.jdt.nullity/src/org/eclipse/objectteams/internal/jdt/nullity/quickfix/RewriteOperations.java
+++ b/plugins/org.eclipse.objectteams.jdt.nullity/src/org/eclipse/objectteams/internal/jdt/nullity/quickfix/RewriteOperations.java
@@ -10,10 +10,14 @@
  *******************************************************************************/
 package org.eclipse.objectteams.internal.jdt.nullity.quickfix;
 
+import java.util.List;
+
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.jdt.core.dom.AST;
 import org.eclipse.jdt.core.dom.Annotation;
 import org.eclipse.jdt.core.dom.BodyDeclaration;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.MarkerAnnotation;
 import org.eclipse.jdt.core.dom.MethodDeclaration;
 import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
 import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;
@@ -29,12 +33,49 @@
 public class RewriteOperations {
 
 	static abstract class SignatureAnnotationRewriteOperation extends CompilationUnitRewriteOperation {
-		String fAnnotation;
+		String fAnnotationToAdd;
+		String fAnnotationToRemove;
+		boolean fAllowRemove;
+		CompilationUnit fUnit;
 		
 		protected String fKey;
 		
 		/** A globally unique key that identifies the position being annotated (for avoiding double annotations). */
 		public String getKey() { return this.fKey; }
+
+		public CompilationUnit getCompilationUnit() {
+			return fUnit;
+		}
+		
+
+		boolean checkExisting(@SuppressWarnings("rawtypes") List existingModifiers, 
+							  ListRewrite listRewrite, 
+							  TextEditGroup editGroup) 
+		{
+			for (Object mod : existingModifiers) {
+				if (mod instanceof MarkerAnnotation) {
+					MarkerAnnotation annotation = (MarkerAnnotation) mod;
+					String existingName = annotation.getTypeName().getFullyQualifiedName();
+					int lastDot = fAnnotationToRemove.lastIndexOf('.');
+					if (   existingName.equals(fAnnotationToRemove)
+						|| (lastDot != -1 && fAnnotationToRemove.substring(lastDot+1).equals(existingName)))
+					{
+						if (!fAllowRemove)
+							return false; // veto this change
+						listRewrite.remove(annotation, editGroup);
+						return true; 
+					}
+					// paranoia: check if by accident the annotation is already present (shouldn't happen):
+					lastDot = fAnnotationToAdd.lastIndexOf('.');
+					if (   existingName.equals(fAnnotationToAdd)
+						|| (lastDot != -1 && fAnnotationToAdd.substring(lastDot+1).equals(existingName)))
+					{
+						return false; // already present
+					}					
+				}
+			}
+			return true;
+		}
 	}
 	
 	/**
@@ -48,24 +89,31 @@
 
 		private final BodyDeclaration fBodyDeclaration;
 
-		public ReturnAnnotationRewriteOperation(MethodDeclaration method, String annotation) {
+		public ReturnAnnotationRewriteOperation(CompilationUnit unit,
+												MethodDeclaration method,
+												String annotationToAdd,
+												String annotationToRemove,
+												boolean allowRemove)
+		{
+			fUnit = unit;
 			fKey= method.resolveBinding().getKey()+"<return>"; //$NON-NLS-1$
 			fBodyDeclaration= method;
-			fAnnotation= annotation;
+			fAnnotationToAdd= annotationToAdd;
+			fAnnotationToRemove= annotationToRemove;
+			fAllowRemove= allowRemove;
 		}
 
-		/**
-		 * {@inheritDoc}
-		 */
 		public void rewriteAST(CompilationUnitRewrite cuRewrite, LinkedProposalModel model) throws CoreException {
 			AST ast= cuRewrite.getRoot().getAST();
 			ListRewrite listRewrite= cuRewrite.getASTRewrite().getListRewrite(fBodyDeclaration, fBodyDeclaration.getModifiersProperty());
+			TextEditGroup group= createTextEditGroup(Messages.format(FixMessages.QuickFixes_declare_method_return_nullable, 
+													 BasicElementLabels.getJavaElementName(fAnnotationToAdd)), cuRewrite);
+			if (!checkExisting(fBodyDeclaration.modifiers(), listRewrite, group))
+				return;
 			Annotation newAnnotation= ast.newMarkerAnnotation();
 			ImportRewrite importRewrite = cuRewrite.getImportRewrite();
-			String resolvableName = importRewrite.addImport(fAnnotation);
+			String resolvableName = importRewrite.addImport(fAnnotationToAdd);
 			newAnnotation.setTypeName(ast.newName(resolvableName));
-			TextEditGroup group= createTextEditGroup(Messages.format(FixMessages.Generic_add_missing_annotation, 
-													 BasicElementLabels.getJavaElementName(fAnnotation)), cuRewrite);
 			listRewrite.insertLast(newAnnotation, group); // null annotation is last modifier, directly preceding the return type
 		}
 	}
@@ -74,13 +122,22 @@
 
 		private SingleVariableDeclaration fArgument;
 
-		public ParameterAnnotationRewriteOperation(MethodDeclaration method, String annotation, String paramName) {
-			fKey = method.resolveBinding().getKey();
-			fAnnotation= annotation;
+		public ParameterAnnotationRewriteOperation(CompilationUnit unit,
+												   MethodDeclaration method,
+												   String annotationToAdd,
+												   String annotationToRemove,
+												   String paramName,
+												   boolean allowRemove)
+		{
+			fUnit= unit;
+			fKey= method.resolveBinding().getKey();
+			fAnnotationToAdd= annotationToAdd;
+			fAnnotationToRemove= annotationToRemove;
+			fAllowRemove= allowRemove;
 			for (Object param : method.parameters()) {
 				SingleVariableDeclaration argument = (SingleVariableDeclaration) param;
 				if (argument.getName().getIdentifier().equals(paramName)) {
-					fArgument = argument;
+					fArgument= argument;
 					fKey += argument.getName().getIdentifier();
 					return;
 				}
@@ -89,16 +146,33 @@
 			throw new RuntimeException("Argument "+paramName+" not found in method "+method.getName().getIdentifier()); //$NON-NLS-1$ //$NON-NLS-2$
 		}
 
-		@Override
+		public ParameterAnnotationRewriteOperation(CompilationUnit unit,
+												   MethodDeclaration method,
+												   String annotationToAdd,
+												   String annotationToRemove,
+												   int paramIdx,
+												   boolean allowRemove)
+		{
+			fUnit= unit;
+			fKey= method.resolveBinding().getKey();
+			fAnnotationToAdd= annotationToAdd;
+			fAnnotationToRemove= annotationToRemove;
+			fAllowRemove= allowRemove;
+			fArgument = (SingleVariableDeclaration) method.parameters().get(paramIdx);
+			fKey += fArgument.getName().getIdentifier();
+		}
+
 		public void rewriteAST(CompilationUnitRewrite cuRewrite, LinkedProposalModel linkedModel) throws CoreException {
 			AST ast= cuRewrite.getRoot().getAST();
 			ListRewrite listRewrite= cuRewrite.getASTRewrite().getListRewrite(fArgument, SingleVariableDeclaration.MODIFIERS2_PROPERTY);
+			TextEditGroup group= createTextEditGroup(Messages.format(FixMessages.QuickFixes_declare_method_parameter_nullable, 
+													 BasicElementLabels.getJavaElementName(fAnnotationToAdd)), cuRewrite);
+			if (!checkExisting(fArgument.modifiers(), listRewrite, group))
+				return;
 			Annotation newAnnotation= ast.newMarkerAnnotation();
 			ImportRewrite importRewrite = cuRewrite.getImportRewrite();
-			String resolvableName = importRewrite.addImport(fAnnotation);
+			String resolvableName = importRewrite.addImport(fAnnotationToAdd);
 			newAnnotation.setTypeName(ast.newName(resolvableName));
-			TextEditGroup group= createTextEditGroup(Messages.format(FixMessages.Generic_add_missing_annotation, 
-													 BasicElementLabels.getJavaElementName(fAnnotation)), cuRewrite);
 			listRewrite.insertLast(newAnnotation, group); // null annotation is last modifier, directly preceding the return type
 		}
 	}