Bug 374840 - [assist] callout completion after parameter mapping garbles
the code
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java
index e7c8fea..a1e6ce5 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java
@@ -8678,6 +8678,9 @@
 
 			for (int i = methodsFound.size; --i >= 0;) {
 				MethodBinding otherMethod = (MethodBinding) methodsFound.elementAt(i);
+//{ObjectTeams: callout override can refer to same methods on both sides:
+			  if (kind != CompletionProposal.OT_CALLOUT_DECLARATION)
+// SH}
 				if (method == otherMethod)
 					continue next;
 
@@ -8685,7 +8688,8 @@
 						&& this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
 //{ObjectTeams: callout (override)? (the ui expands callout to a choice of any method binding)
 					if (curKind != CompletionProposal.METHOD_DECLARATION) {
-						if (otherMethod.declaringClass.isCompatibleWith(method.declaringClass))
+						if (otherMethod.declaringClass.isCompatibleWith(method.declaringClass)
+						    && !receiverType.isCompatibleWith(method.declaringClass))
 							continue next; // comparing two base methods.
 						if (MethodModel.isAbstract(otherMethod)) {
 							curKind = CompletionProposal.OT_CALLOUT_DECLARATION;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
index 8a02979..f886e5b 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
@@ -13440,7 +13440,8 @@
 		}
 		if (haveTokenWith)
 		{
-			methodMapping.declarationSourceEnd = this.scanner.currentPosition; // before 'with'
+			// don't set declarationSourceEnd, but let RecoveredMethodMapping.updateSourceEndIfNecessary() do so
+			methodMapping.mappings = AbstractMethodMappingDeclaration.PENDING_MAPPINGS;
 			try {
 				this.currentToken = this.scanner.getNextToken(); // skip 'with', try to find '{'
 			} catch (InvalidInputException e) {
diff --git a/testplugins/org.eclipse.objectteams.otdt.ui.tests/src/org/eclipse/objectteams/otdt/ui/tests/core/CodeCompletionTest.java b/testplugins/org.eclipse.objectteams.otdt.ui.tests/src/org/eclipse/objectteams/otdt/ui/tests/core/CodeCompletionTest.java
index 3964ba7..ccecbfc 100644
--- a/testplugins/org.eclipse.objectteams.otdt.ui.tests/src/org/eclipse/objectteams/otdt/ui/tests/core/CodeCompletionTest.java
+++ b/testplugins/org.eclipse.objectteams.otdt.ui.tests/src/org/eclipse/objectteams/otdt/ui/tests/core/CodeCompletionTest.java
@@ -106,7 +106,7 @@
 			return allTests();
 		} else {
 			TestSuite suite= new TestSuite();
-			suite.addTest(new CodeCompletionTest("testOverrideRole3"));
+			suite.addTest(new CodeCompletionTest("testCreateCalloutOverride3"));
 			return new ProjectTestSetup(suite);
 		}
 	}
@@ -435,6 +435,53 @@
 		assertProposal("setBlub(int)", null, null, subTeamContent, new Region(pos, 0), expectedContent, new Region(posAfter+2, 0), 0);  
 	}
 	
+	
+	// Bug 374840 - [assist] callout completion after parameter mapping garbles the code
+	public void testCreateCalloutOverride3() throws Exception {
+		IPackageFragment pkg = CompletionTestSetup.getTestPackage("p1");
+		
+		pkg.createCompilationUnit("ABase.java", 
+				"package test1.p1;\n" +
+				"public class ABase {\n" +
+				"	Object blub;\n" +
+				"}\n", 
+				true, null);
+		
+		StringBuffer subTeamContent = new StringBuffer(); 
+		subTeamContent.append("package test1;\n");
+		subTeamContent.append("import base test1.p1.ABase;\n");
+		subTeamContent.append("public team class Completion_testCreateCalloutOverride3 {\n");
+		subTeamContent.append("    protected class MyRole playedBy ABase {\n");
+		subTeamContent.append("		public String getBlubString() -> get Object blub\n");
+		subTeamContent.append("		    with { result <- blub.toString() }\n");
+		subTeamContent.append("		toStr\n");
+		subTeamContent.append("    }\n");
+		subTeamContent.append("}");
+		
+		StringBuffer expectedContent = new StringBuffer(); 
+		expectedContent.append("package test1;\n");
+		expectedContent.append("import base test1.p1.ABase;\n");
+		expectedContent.append("public team class Completion_testCreateCalloutOverride3 {\n");
+		expectedContent.append("    protected class MyRole playedBy ABase {\n");
+		expectedContent.append("		public String getBlubString() -> get Object blub\n");
+		expectedContent.append("		    with { result <- blub.toString() }\n");
+		expectedContent.append("\n");
+		expectedContent.append("        /* (non-Javadoc)\n");
+		expectedContent.append("         * @see java.lang.Object#toString()\n");
+		expectedContent.append("         */\n");
+		expectedContent.append("        String toString() => String toString();\n");
+		expectedContent.append("		\n");
+		expectedContent.append("    }\n");
+		expectedContent.append("}");
+
+		String completeAfter = "		toStr";
+		int pos = subTeamContent.indexOf(completeAfter)+completeAfter.length();
+		int posAfter = expectedContent.indexOf("String toString");
+		
+		// discriminate from method override:
+		assertProposal("toString()  String", null, null, subTeamContent, new Region(pos, 0), expectedContent, new Region(posAfter, "String".length()), 0); 
+	}
+	
 
 	public void testCompleteCallout1() throws Exception {
 		createBaseClass("    public void foo() {}\n");