Bug 577270 - Disambiguation for '->' fails with latest changes from JDT
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionScanner.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionScanner.java
index 669ad78..fc21481 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionScanner.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionScanner.java
@@ -293,12 +293,13 @@
 							return TokenNameARROW;
   :giro */
 						if (getNextChar('>')) {
-							if (this._isOTSource) {
-								this._calloutSeen = true; // TODO distinguish from ARROW?
+							if (needBindoutDisambiguation()) {
 								if (this._insideParameterMapping) {
 									this._bindoutLookahead = new BindoutLookahead();
 									return this._bindoutLookahead.getNextToken();
 								}
+								this._calloutSeen = true;
+								return TokenNameSYNTHBINDOUT;
 							}
 							return TokenNameARROW;
 						}
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 14da02e..2dd4aaa 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
@@ -2815,7 +2815,7 @@
 	// CalloutKind
 	calloutBinding.calloutKind       = this.intStack[this.intPtr--];
 	calloutBinding.bindingTokenStart = this.intStack[this.intPtr--];
-	if (calloutBinding.calloutKind == TokenNameBINDOUT) // as apposed to '=>'
+	if (calloutBinding.calloutKind == TokenNameSYNTHBINDOUT) // as opposed to '=>'
 		this.intPtr--; // from Scanner.currentPosition for LE.arrowPosition
 	calloutBinding.modifierEnd = calloutBinding.bindingTokenStart+1; // assume just '->' or '=>', until we find actual callout modifiers (get/set)
 
@@ -4006,7 +4006,7 @@
 				this.currentElement = this.currentElement.parent;
 			}
 //{ObjectTeams: recover method mapping:
-		} else if (this.currentToken == TokenNameBINDOUT) {
+		} else if (this.currentToken == TokenNameSYNTHBINDOUT) {
 			// TODO(SH): element should have been a callout mapping (missing return type)
 			//           create RecoveredMethodMapping.
 // SH}
@@ -12540,7 +12540,8 @@
 	//System.out.println(this.scanner.toStringAction(type));
 	switch (type) {
 		case TokenNameARROW:
-//{ObjectTeams: for alias TokenNameBINDOUT
+//{ObjectTeams: for alias TokenNameSYNTHBINDOUT
+		case TokenNameSYNTHBINDOUT:
 			pushOnIntStack(this.scanner.currentPosition); // for LE.arrowPosition
 			pushOnIntStack(this.scanner.startPosition); // for bindingTokenStart
 			pushOnIntStack(type);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredMethodMapping.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredMethodMapping.java
index f7ffc1f..b3a73d6 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredMethodMapping.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredMethodMapping.java
@@ -153,7 +153,7 @@
 		switch (nextToken) {
 		case TerminalTokens.TokenNameLBRACE:   // it's a real method
 		case TerminalTokens.TokenNameBINDIN:   // it's the start of a new callin mapping
-		case TerminalTokens.TokenNameBINDOUT:  // it's the start of a new callout mapping
+		case TerminalTokens.TokenNameSYNTHBINDOUT:  // it's the start of a new callout mapping
 			// add real method or mapping to the class:
 			return super.add(methodDeclaration, bracketBalanceValue);
 		}
@@ -220,7 +220,7 @@
 	// check whether fieldDeclaration is a misread method spec rather than a real field
 	switch (parser().currentToken) {
 	case TerminalTokens.TokenNameBINDIN:   // it's the start of a new callin mapping
-	case TerminalTokens.TokenNameBINDOUT:  // it's the start of a new callout mapping
+	case TerminalTokens.TokenNameSYNTHBINDOUT:  // it's the start of a new callout mapping
 		// ignore misread field:
 		return this;
 	}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java
index 5bea2fd..beb8060 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java
@@ -28,7 +28,12 @@
 import org.eclipse.jdt.core.compiler.InvalidInputException;
 import org.eclipse.jdt.internal.compiler.CompilationResult;
 import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
+import org.eclipse.jdt.internal.compiler.ast.Argument;
+import org.eclipse.jdt.internal.compiler.ast.LambdaExpression;
+import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
 import org.eclipse.jdt.internal.compiler.ast.Statement;
+import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
 import org.eclipse.jdt.internal.compiler.impl.JavaFeature;
@@ -235,7 +240,7 @@
     		return baseIsKeyword(false);
     	case TokenNameas:
     	case TokenNameBINDIN:
-    	case TokenNameBINDOUT:
+    	case TokenNameSYNTHBINDOUT:
     	case TokenNamecallin:
     	case TokenNameplayedBy:
     	case TokenNameprecedence:
@@ -1785,12 +1790,13 @@
 							return TokenNameARROW;
   :giro */
 						if (getNextChar('>')) {
-							if (this._isOTSource) {
-								this._calloutSeen = true; // TODO distinguish from ARROW?
+							if (needBindoutDisambiguation()) {
 								if (this._insideParameterMapping) {
 									this._bindoutLookahead = new BindoutLookahead();
 									return this._bindoutLookahead.getNextToken();
 								}
+								this._calloutSeen = true;
+								return TokenNameSYNTHBINDOUT;
 							}
 							return TokenNameARROW;
 						}
@@ -2242,6 +2248,34 @@
 	}
 	return TokenNameEOF;
 }
+protected boolean needBindoutDisambiguation() {
+	if (!this._isOTSource)
+		return false;
+	if (this._calloutSeen || this._callinSeen)
+		return false; // no nesting
+	if (this.activeParser instanceof VanguardParser) {
+		Goal goal = ((VanguardParser)this.activeParser).currentGoal;
+		return !(goal == Goal.LambdaParameterListGoal || goal == Goal.PatternGoal);
+	} else if (this.activeParser instanceof Parser) {
+		Parser parser = (Parser) this.activeParser;
+		int ptr = parser.astPtr;
+		while (ptr > -1) {
+			ASTNode topAstNode = parser.astStack[ptr];
+			if (topAstNode instanceof TypeDeclaration) {
+				return true;
+			} else if (topAstNode instanceof MethodDeclaration) {
+				return true; // method to be reclassified as MethodSpec :( TODO: test content?
+			} else if (topAstNode instanceof LambdaExpression) {
+				return topAstNode.sourceEnd != 0; // disambiguation only when body is complete
+			} else if (topAstNode instanceof Argument) {
+				ptr--; // dig deeper
+			} else {
+				return true;
+			}
+		}
+	}
+	return true;
+}
 private int scanForStringLiteral() throws InvalidInputException {
 	boolean isTextBlock = false;
 
@@ -5906,6 +5940,14 @@
 	}
 	this.vanguardScanner.setSource(this.source);
 	this.vanguardScanner.resetTo(this.startPosition, this.eofPosition - 1, isInModuleDeclaration(), this.scanContext);
+//{ObjectTeams: init OT-state:
+	this.vanguardScanner._isOTSource = this._isOTSource;
+	this.vanguardScanner._dotSeen = this._dotSeen;
+	this.vanguardScanner._calloutSeen = this._calloutSeen;
+	this.vanguardScanner._callinSeen = this._callinSeen;
+	this.vanguardScanner._insideParameterMapping = this._insideParameterMapping;
+	this.vanguardScanner._forceBaseIsIdentifier = this._forceBaseIsIdentifier;
+// SH}
 	return this.vanguardParser;
 }
 private VanguardParser getNewVanguardParser() {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/TerminalTokens.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/TerminalTokens.java
index df23a73..050dcae 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/TerminalTokens.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/TerminalTokens.java
@@ -42,29 +42,29 @@
 	// BEGIN_AUTOGENERATED_REGION
 	int TokenNameIdentifier = 14,
 							TokenNameabstract = 56,
-							TokenNameassert = 89,
+							TokenNameassert = 88,
 							TokenNameboolean = 116,
-							TokenNamebreak = 90,
+							TokenNamebreak = 89,
 							TokenNamebyte = 117,
 							TokenNamecase = 115,
 							TokenNamecatch = 118,
 							TokenNamechar = 119,
-							TokenNameclass = 74,
-							TokenNamecontinue = 91,
+							TokenNameclass = 75,
+							TokenNamecontinue = 90,
 							TokenNameconst = 152,
-							TokenNamedefault = 83,
-							TokenNamedo = 92,
+							TokenNamedefault = 82,
+							TokenNamedo = 91,
 							TokenNamedouble = 120,
 							TokenNameelse = 133,
 							TokenNameenum = 79,
-							TokenNameextends = 100,
+							TokenNameextends = 99,
 							TokenNamefalse = 42,
 							TokenNamefinal = 57,
 							TokenNamefinally = 129,
 							TokenNamefloat = 121,
-							TokenNamefor = 93,
+							TokenNamefor = 92,
 							TokenNamegoto = 153,
-							TokenNameif = 94,
+							TokenNameif = 93,
 							TokenNameimplements = 149,
 							TokenNameimport = 122,
 							TokenNameinstanceof = 18,
@@ -75,11 +75,11 @@
 							TokenNamenew = 37,
 							TokenNamenon_sealed = 59,
 							TokenNamenull = 43,
-							TokenNamepackage = 101,
+							TokenNamepackage = 100,
 							TokenNameprivate = 60,
 							TokenNameprotected = 61,
 							TokenNamepublic = 62,
-							TokenNamereturn = 95,
+							TokenNamereturn = 94,
 							TokenNameshort = 125,
 							TokenNamestatic = 40,
 							TokenNamestrictfp = 63,
@@ -87,14 +87,14 @@
 							TokenNameswitch = 67,
 							TokenNamesynchronized = 53,
 							TokenNamethis = 36,
-							TokenNamethrow = 86,
+							TokenNamethrow = 85,
 							TokenNamethrows = 126,
 							TokenNametransient = 64,
 							TokenNametrue = 44,
-							TokenNametry = 96,
+							TokenNametry = 95,
 							TokenNamevoid = 127,
 							TokenNamevolatile = 65,
-							TokenNamewhile = 87,
+							TokenNamewhile = 86,
 							TokenNamemodule = 130,
 							TokenNameopen = 131,
 							TokenNamerequires = 134,
@@ -104,16 +104,16 @@
 							TokenNameto = 150,
 							TokenNameuses = 137,
 							TokenNameprovides = 138,
-							TokenNamewith = 102,
+							TokenNamewith = 101,
 							TokenNameas = 142,
 							TokenNamebase = 33,
 							TokenNamecallin = 66,
 							TokenNameplayedBy = 151,
-							TokenNameprecedence = 103,
+							TokenNameprecedence = 102,
 							TokenNameteam = 54,
 							TokenNametsuper = 38,
-							TokenNamewhen = 99,
-							TokenNamewithin = 97,
+							TokenNamewhen = 98,
+							TokenNamewithin = 96,
 							TokenNamereplace = 143,
 							TokenNameafter = 139,
 							TokenNamebefore = 144,
@@ -135,17 +135,17 @@
 							TokenNameLEFT_SHIFT = 19,
 							TokenNameRIGHT_SHIFT = 13,
 							TokenNameUNSIGNED_RIGHT_SHIFT = 17,
-							TokenNamePLUS_EQUAL = 104,
-							TokenNameMINUS_EQUAL = 105,
-							TokenNameMULTIPLY_EQUAL = 106,
-							TokenNameDIVIDE_EQUAL = 107,
-							TokenNameAND_EQUAL = 108,
-							TokenNameOR_EQUAL = 109,
-							TokenNameXOR_EQUAL = 110,
-							TokenNameREMAINDER_EQUAL = 111,
-							TokenNameLEFT_SHIFT_EQUAL = 112,
-							TokenNameRIGHT_SHIFT_EQUAL = 113,
-							TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL = 114,
+							TokenNamePLUS_EQUAL = 103,
+							TokenNameMINUS_EQUAL = 104,
+							TokenNameMULTIPLY_EQUAL = 105,
+							TokenNameDIVIDE_EQUAL = 106,
+							TokenNameAND_EQUAL = 107,
+							TokenNameOR_EQUAL = 108,
+							TokenNameXOR_EQUAL = 109,
+							TokenNameREMAINDER_EQUAL = 110,
+							TokenNameLEFT_SHIFT_EQUAL = 111,
+							TokenNameRIGHT_SHIFT_EQUAL = 112,
+							TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL = 113,
 							TokenNameOR_OR = 31,
 							TokenNameAND_AND = 29,
 							TokenNamePLUS = 4,
@@ -165,33 +165,33 @@
 							TokenNameLBRACE = 41,
 							TokenNameRBRACE = 34,
 							TokenNameLBRACKET = 6,
-							TokenNameRBRACKET = 73,
+							TokenNameRBRACKET = 74,
 							TokenNameSEMICOLON = 25,
 							TokenNameQUESTION = 30,
 							TokenNameCOLON = 68,
 							TokenNameCOMMA = 32,
 							TokenNameDOT = 1,
-							TokenNameEQUAL = 84,
+							TokenNameEQUAL = 83,
 							TokenNameAT = 39,
 							TokenNameELLIPSIS = 132,
-							TokenNameARROW = 81,
+							TokenNameARROW = 114,
 							TokenNameCOLON_COLON = 7,
 							TokenNameBeginLambda = 52,
 							TokenNameBeginIntersectionCast = 72,
-							TokenNameBeginTypeArguments = 85,
-							TokenNameElidedSemicolonAndRightBrace = 75,
+							TokenNameBeginTypeArguments = 84,
+							TokenNameElidedSemicolonAndRightBrace = 76,
 							TokenNameAT308 = 26,
 							TokenNameAT308DOTDOTDOT = 147,
-							TokenNameBeginCaseExpr = 76,
-							TokenNameRestrictedIdentifierYield = 88,
+							TokenNameBeginCaseExpr = 77,
+							TokenNameRestrictedIdentifierYield = 87,
 							TokenNameRestrictedIdentifierrecord = 80,
 							TokenNameRestrictedIdentifiersealed = 55,
 							TokenNameRestrictedIdentifierpermits = 140,
 							TokenNameBeginCaseElement = 148,
 							TokenNameATOT = 128,
-							TokenNameBINDIN = 82,
-							TokenNameCALLOUT_OVERRIDE = 98,
-							TokenNameSYNTHBINDOUT = 77,
+							TokenNameBINDIN = 81,
+							TokenNameCALLOUT_OVERRIDE = 97,
+							TokenNameSYNTHBINDOUT = 73,
 							TokenNameEOF = 69,
 							TokenNameERROR = 154;
 
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser1.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser1.rsc
index 40afae8..d0e7d00 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser1.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser1.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser14.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser14.rsc
index 593a3fe..fc813e5 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser14.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser14.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser16.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser16.rsc
index d40c3ab..a96d6d5 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser16.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser16.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser18.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser18.rsc
index 9c2fe70..babca65 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser18.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser18.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser19.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser19.rsc
index 17e7aad..003d145 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser19.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser19.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser23.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser23.rsc
index e0dc560..bb17124 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser23.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser23.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser3.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser3.rsc
index 23aa7b4..9e58de8 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser3.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser3.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser4.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser4.rsc
index f24e892..28f2a9f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser4.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser4.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser7.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser7.rsc
index 3ff9f69..a15c000 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser7.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser7.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser9.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser9.rsc
index 2437905..c5ff57a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser9.rsc
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser9.rsc
Binary files differ
diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java
index 2577755..e8465a0 100644
--- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java
+++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/internal/core/dom/rewrite/ASTRewriteAnalyzer.java
@@ -5008,7 +5008,7 @@
 		MethodBindingOperator bindingOp = node.bindingOperator();
 		int oldBindingKind= ((Integer) getOriginalValue(bindingOp, MethodBindingOperator.BINDING_KIND_PROPERTY)).intValue();
 		boolean isCalloutOverride = (oldBindingKind == MethodBindingOperator.KIND_CALLOUT_OVERRIDE);
-		int typeToken= isCalloutOverride ? TerminalTokens.TokenNameCALLOUT_OVERRIDE : TerminalTokens.TokenNameBINDOUT;
+		int typeToken= isCalloutOverride ? TerminalTokens.TokenNameCALLOUT_OVERRIDE : TerminalTokens.TokenNameSYNTHBINDOUT;
 		try {
 			getScanner().readToToken(typeToken, node.getStartPosition());
 		} catch (CoreException e) {
diff --git a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/SpacePreparator.java b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/SpacePreparator.java
index 36d8172..aed39a8 100644
--- a/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/SpacePreparator.java
+++ b/org.eclipse.jdt.core/formatter/org/eclipse/jdt/internal/formatter/SpacePreparator.java
@@ -1108,7 +1108,7 @@
 	}
 	@Override
 	public boolean visit(CalloutMappingDeclaration node) {
-		handleTokenAfter(node.getRoleMappingElement(), node.isCalloutOverride() ? TokenNameCALLOUT_OVERRIDE : TokenNameBINDOUT, true, true);
+		handleTokenAfter(node.getRoleMappingElement(), node.isCalloutOverride() ? TokenNameCALLOUT_OVERRIDE : TokenNameSYNTHBINDOUT, true, true);
 		if (node.hasParameterMapping())
 			handleTokenAfter(node.getBaseMappingElement(), TokenNamewith, true, true);
 		return true;
@@ -1137,7 +1137,7 @@
 		if (node.isBindIN())
 			handleTokenAfter(node.getIdentifier(), TokenNameBINDIN, true, true);
 		else
-			handleTokenBefore(node.getIdentifier(), TokenNameBINDOUT, true, true);
+			handleTokenBefore(node.getIdentifier(), TokenNameSYNTHBINDOUT, true, true);
 		return true;
 	}
 	@Override
diff --git a/org.eclipse.jdt.core/grammar/java.g b/org.eclipse.jdt.core/grammar/java.g
index 8d16804..e5b2a18 100644
--- a/org.eclipse.jdt.core/grammar/java.g
+++ b/org.eclipse.jdt.core/grammar/java.g
@@ -1156,7 +1156,7 @@
 /.$putCase consumeCalloutParameterMappingsInvalid(); $break ./
 
 -- SYMBOLS:
-CalloutKind -> '->'
+CalloutKind -> SYNTHBINDOUT
 CalloutKind -> '=>'
 /:$readableName CalloutKind:/
 
diff --git a/org.eclipse.jdt.core/scripts/generateParser.launch b/org.eclipse.jdt.core/scripts/generateParser.launch
index 44b9189..1c3d0c8 100644
--- a/org.eclipse.jdt.core/scripts/generateParser.launch
+++ b/org.eclipse.jdt.core/scripts/generateParser.launch
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <launchConfiguration type="org.eclipse.ui.externaltools.ProgramLaunchConfigurationType">
-<stringAttribute key="bad_container_name" value="/org.eclipse.jdt.core/scripts/generateParser.launch"/>
-<stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${working_set:&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;resources&gt;&#10;&lt;item path=&quot;/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser&quot; type=&quot;2&quot;/&gt;&#10;&lt;/resources&gt;}"/>
-<mapAttribute key="org.eclipse.debug.core.environmentVariables">
-<mapEntry key="JAVAC" value="/home/java/jdk1.8.0/bin/javac"/>
-<mapEntry key="JIKESPG_HOME" value="${system_property:user.home}/bin"/>
-</mapAttribute>
-<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LAUNCH_CONFIGURATION_BUILD_SCOPE" value="${project}"/>
-<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/org.eclipse.jdt.core/scripts/generateOTParser.sh}"/>
-<stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="../grammar/java.g .."/>
-<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${workspace_loc:/org.eclipse.jdt.core/scripts}"/>
+    <stringAttribute key="bad_container_name" value="/org.eclipse.jdt.core/scripts/generateParser.launch"/>
+    <stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${working_set:&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;resources&gt;&#10;&lt;item path=&quot;/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser&quot; type=&quot;2&quot;/&gt;&#10;&lt;/resources&gt;}"/>
+    <mapAttribute key="org.eclipse.debug.core.environmentVariables">
+        <mapEntry key="JAVAC" value="/home/java/jdk-11/bin/javac"/>
+        <mapEntry key="JIKESPG_HOME" value="${system_property:user.home}/bin"/>
+    </mapAttribute>
+    <stringAttribute key="org.eclipse.ui.externaltools.ATTR_LAUNCH_CONFIGURATION_BUILD_SCOPE" value="${project}"/>
+    <stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/org.eclipse.jdt.core/scripts/generateOTParser.sh}"/>
+    <stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="../grammar/java.g .."/>
+    <stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${workspace_loc:/org.eclipse.jdt.core/scripts}"/>
 </launchConfiguration>
diff --git a/testplugins/org.eclipse.objectteams.otdt.tests/compiler/org/eclipse/objectteams/otdt/tests/compiler/AttributesTest.java b/testplugins/org.eclipse.objectteams.otdt.tests/compiler/org/eclipse/objectteams/otdt/tests/compiler/AttributesTest.java
index 6a68993..50a4c2c 100644
--- a/testplugins/org.eclipse.objectteams.otdt.tests/compiler/org/eclipse/objectteams/otdt/tests/compiler/AttributesTest.java
+++ b/testplugins/org.eclipse.objectteams.otdt.tests/compiler/org/eclipse/objectteams/otdt/tests/compiler/AttributesTest.java
@@ -60,6 +60,10 @@
 			this.versionString = "version 14 : 58.0";
 		} else if (this.complianceLevel == ClassFileConstants.JDK15) {
 			this.versionString = "version 15 : 59.0";
+		} else if (this.complianceLevel == ClassFileConstants.JDK16) {
+			this.versionString = "version 16 : 60.0";
+		} else if (this.complianceLevel == ClassFileConstants.JDK17) {
+			this.versionString = "version 17 : 61.0";
 		}
 	}
 
diff --git a/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/calloutbinding/CalloutParameterBinding_LiftingAndLowering.java b/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/calloutbinding/CalloutParameterBinding_LiftingAndLowering.java
index b2408e5..aea8eb6 100644
--- a/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/calloutbinding/CalloutParameterBinding_LiftingAndLowering.java
+++ b/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/calloutbinding/CalloutParameterBinding_LiftingAndLowering.java
@@ -317,7 +317,6 @@
     // a callout binding has a syntax error (hang reported by Philippe Gerard)
     // 3.2.1-otjld-callout-invocation-with-mapped-parameter-6
     public void test321_calloutInvocationWithMappedParameter6() {
-    	boolean isJ14plus = this.complianceLevel >= ClassFileConstants.JDK14;
         runNegativeTest(
             new String[] {
 		"Team321ciwmp6.java",
@@ -346,154 +345,65 @@
 			    "}\n" +
 			    "    \n"
             },
-            "----------\n" +
-    		"1. ERROR in Team321ciwmp6.java (at line 1)\n" +
-    		"	\n" +
-    		"public team class Team321ciwmp6 {\n" +
-    		"	^\n" +
-    		"Syntax error on token \";\", ++ expected before this token\n" +
-    		"----------\n" +
-    		( this.complianceLevel < ClassFileConstants.JDK1_8
-    		?
-	    		"2. ERROR in Team321ciwmp6.java (at line 5)\n" +
-	    		"	int doSomethingOther(int r1) -> int doSomething(int b1) wrong\n" +
-	    		"                        with {\n" +
-	    		"	                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
-	    		"Syntax error on tokens, EmptyParameterMappings expected instead\n" +
-	    		"----------\n" +
-	    		"3. ERROR in Team321ciwmp6.java (at line 7)\n" +
-	    		"	r1 -> b1,\n" +
-	    		"	        ^\n" +
-	    		"Syntax error on token \",\", ; expected\n"+
-	    		"----------\n" +
-	    		"4. ERROR in Team321ciwmp6.java (at line 9)\n" +
-	    		"	};\n" +
-	    		"	 ^\n" +
-	    		"Syntax error, insert \"}\" to complete ClassBody\n" +
-	    		"----------\n" +
-	    		"5. ERROR in Team321ciwmp6.java (at line 11)\n" +
-	    		"	int doCalloutGetSomeFieldDoubled() -> get int someField\n" +
-	    		"	^^^\n" +
-	    		"Syntax error on token \"int\", @ expected\n" +
-	    		"----------\n" +
-	    		"6. ERROR in Team321ciwmp6.java (at line 11)\n" +
-	    		"	int doCalloutGetSomeFieldDoubled() -> get int someField\n" +
-	    		"                        with {\n" +
-	    		"	^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
-	    		"Syntax error on tokens, ClassHeader expected instead\n" +
-	    		"----------\n" +
-	    		"7. ERROR in Team321ciwmp6.java (at line 12)\n" +
-	    		"	with {\n" +
-	    		"                                result <- 2 * base.someField\n" +
-	    		"	      ^\n" +
-	    		"Syntax error on token \";\", & expected before this token\n" +
-	    		"----------\n" +
-	    		"8. ERROR in Team321ciwmp6.java (at line 13)\n" +
-	    		"	result <- 2 * base.someField\n" +
-	    		"	^^^^^^^^^^^^^\n" +
-	    		"Syntax error on tokens, delete these tokens\n" +
-	    		"----------\n" +
-	    		"9. ERROR in Team321ciwmp6.java (at line 13)\n" +
-	    		"	result <- 2 * base.someField\n" +
-	    		"	              ^^^^^\n" +
-	    		"Syntax error on tokens, delete these tokens\n" +
-	    		"----------\n" +
-	    		"10. ERROR in Team321ciwmp6.java (at line 13)\n" +
-	    		"	result <- 2 * base.someField\n" +
-	    		"	                  ^\n" +
-	    		"Syntax error, insert \"enum Identifier\" to complete EnumHeaderName\n" +
-	    		"----------\n" +
-	    		"11. ERROR in Team321ciwmp6.java (at line 13)\n" +
-	    		"	result <- 2 * base.someField\n" +
-	    		"	                  ^\n" +
-	    		"Syntax error, insert \"EnumBody\" to complete ClassBodyDeclarations\n" +
-	    		"----------\n" +
-	    		"12. ERROR in Team321ciwmp6.java (at line 15)\n" +
-	    		"	}\n" +
-	    		"}\n" +
-	    		"	^^^\n" +
-	    		"Syntax error on tokens, delete these tokens\n" +
-	    		"----------\n"
-    		:
-        		"2. ERROR in Team321ciwmp6.java (at line 5)\n" +
-        		"	int doSomethingOther(int r1) -> int doSomething(int b1) wrong\n" +
-        		"	                                                        ^^^^^\n" +
-        		"Syntax error on token \"wrong\", delete this token\n" +
-        		"----------\n" +
-        		"3. ERROR in Team321ciwmp6.java (at line 7)\n" +
-        		"	r1 -> b1,\n" +
-        		"	      ^^\n" +
-        		"Syntax error, insert \"AssignmentOperator Expression\" to complete Assignment\n" +
-        		"----------\n" +
-        		"4. ERROR in Team321ciwmp6.java (at line 7)\n" +
-        		"	r1 -> b1,\n" +
-        		"	      ^^\n" +
-        		"Syntax error, insert \"-> Identifier\" to complete ParameterMapping\n" +
-        		"----------\n" +
-        		"5. ERROR in Team321ciwmp6.java (at line 9)\n" +
-        		"	};\n" +
-        		"	 ^\n" +
-        		"Syntax error, insert \"}\" to complete ClassBody\n" +
-        		"----------\n" +
-        		"6. ERROR in Team321ciwmp6.java (at line 9)\n" +
-        		"	};\n" +
-        		"	 ^\n" +
-        		"Syntax error, insert \"}\" to complete ClassBody\n" +
-        		"----------\n" +
-        		"7. ERROR in Team321ciwmp6.java (at line 11)\n" +
-        		"	int doCalloutGetSomeFieldDoubled() -> get int someField\n" +
-        		"	^^^\n" +
-	    		(isJ14plus
-	    		? "Syntax error on token \"int\", record expected\n"
-	    		: "Syntax error on token \"int\", @ expected\n") +
-        		"----------\n" +
-        		"8. ERROR in Team321ciwmp6.java (at line 11)\n" +
-        		"	int doCalloutGetSomeFieldDoubled() -> get int someField\n" +
-        		"                        with {\n" +
-	    		(isJ14plus
-				? "	                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
-				  "Syntax error on tokens, delete these tokens\n"
-	    		: "	^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
-        		"Syntax error on tokens, ClassHeader expected instead\n") +
-        		"----------\n" +
-        		"9. ERROR in Team321ciwmp6.java (at line 12)\n" +
-        		"	with {\n" +
-        		"                                result <- 2 * base.someField\n" +
-        		"	      ^\n" +
-        		"Syntax error on token \";\", & expected before this token\n" +
-        		"----------\n" +
-        		"10. ERROR in Team321ciwmp6.java (at line 13)\n" +
-        		"	result <- 2 * base.someField\n" +
-        		"	^^^^^^^^^^^^^\n" +
-        		"Syntax error on tokens, delete these tokens\n" +
-        		"----------\n" +
-        		"11. ERROR in Team321ciwmp6.java (at line 13)\n" +
-        		"	result <- 2 * base.someField\n" +
-        		"	              ^^^^^\n" +
-        		"Syntax error on tokens, delete these tokens\n" +
-        		"----------\n" +
-        		"12. ERROR in Team321ciwmp6.java (at line 13)\n" +
-        		"	result <- 2 * base.someField\n" +
-        		"	                  ^\n" +
-        		"Syntax error, insert \"enum Identifier\" to complete EnumHeaderName\n" +
-        		"----------\n" +
-        		"13. ERROR in Team321ciwmp6.java (at line 13)\n" +
-        		"	result <- 2 * base.someField\n" +
-        		"	                  ^\n" +
-        		"Syntax error, insert \"EnumBody\" to complete ClassBodyDeclarations\n" +
-        		"----------\n" +
-        		(isJ14plus
-				? "14. ERROR in Team321ciwmp6.java (at line 14)\n" +
-				  "	};\n" +
-				  "	^\n" +
-				  "Syntax error on token \"}\", { expected\n"
-        		: "14. ERROR in Team321ciwmp6.java (at line 15)\n" +
-        		"	}\n" +
-        		"}\n" +
-        		"	^^^\n" +
-        		"Syntax error on tokens, delete these tokens\n") +
-        		"----------\n"
-    		));
+            "----------\n" + 
+    		"1. ERROR in Team321ciwmp6.java (at line 1)\n" + 
+    		"	\n" + 
+    		"public team class Team321ciwmp6 {\n" + 
+    		"	^\n" + 
+    		"Syntax error on token \"++\", || expected before this token\n" + 
+    		"----------\n" + 
+    		"2. ERROR in Team321ciwmp6.java (at line 1)\n" + 
+    		"	\n" + 
+    		"public team class Team321ciwmp6 {\n" + 
+    		"	^\n" + 
+    		"Syntax error on token \";\", ++ expected before this token\n" + 
+    		"----------\n" + 
+    		"3. ERROR in Team321ciwmp6.java (at line 5)\n" + 
+    		"	int doSomethingOther(int r1) -> int doSomething(int b1) wrong\n" + 
+    		"	                                                        ^^^^^\n" + 
+    		"Syntax error on token \"wrong\", delete this token\n" + 
+    		"----------\n" + 
+    		"4. ERROR in Team321ciwmp6.java (at line 9)\n" + 
+    		"	};\n" + 
+    		"	 ^\n" + 
+    		"Syntax error, insert \"}\" to complete ClassBody\n" + 
+    		"----------\n" + 
+    		"5. ERROR in Team321ciwmp6.java (at line 9)\n" + 
+    		"	};\n" + 
+    		"	 ^\n" + 
+    		"Syntax error, insert \"}\" to complete ClassBody\n" + 
+    		"----------\n" + 
+    		"6. ERROR in Team321ciwmp6.java (at line 11)\n" + 
+    		"	int doCalloutGetSomeFieldDoubled() -> get int someField\n" + 
+    		"	                                ^\n" + 
+    		"Syntax error, insert \")\" to complete MethodDeclaration\n" + 
+    		"----------\n" + 
+    		"7. ERROR in Team321ciwmp6.java (at line 11)\n" + 
+    		"	int doCalloutGetSomeFieldDoubled() -> get int someField\n" + 
+    		"	                                ^\n" + 
+    		"Syntax error, insert \";\" to complete MethodDeclaration\n" + 
+    		"----------\n" + 
+    		"8. ERROR in Team321ciwmp6.java (at line 13)\n" + 
+    		"	result <- 2 * base.someField\n" + 
+    		"	^^^^^^\n" + 
+    		"No method result found in type Team321ciwmp6.Role to resolve method designator (OTJLD 4.1(c)).\n" + 
+    		"----------\n" + 
+    		"9. ERROR in Team321ciwmp6.java (at line 13)\n" + 
+    		"	result <- 2 * base.someField\n" + 
+    		"	                  ^\n" + 
+    		"Syntax error on token \".\", delete this token\n" + 
+    		"----------\n" + 
+    		"10. ERROR in Team321ciwmp6.java (at line 13)\n" + 
+    		"	result <- 2 * base.someField\n" + 
+    		"	                  ^\n" + 
+    		"Syntax error, insert \":: IdentifierOrNew\" to complete Expression\n" + 
+    		"----------\n" + 
+    		"11. ERROR in Team321ciwmp6.java (at line 13)\n" + 
+    		"	result <- 2 * base.someField\n" + 
+    		"	                   ^^^^^^^^^\n" + 
+    		"No method someField found in type T321ciwmp6 to resolve method designator (OTJLD 4.1(c)).\n" + 
+    		"----------\n"
+		);
     }
 
     // an invocation of a callout-bound base method from the direct base class that has a implicit result mapping