HEAD - bug 116419
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/CompletionParserTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/CompletionParserTest.java
index 799e5db..76feddb 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/CompletionParserTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/CompletionParserTest.java
@@ -8615,4 +8615,35 @@
 		expectedReplacedSource,
 		testName); 
 }
+
+public void test017(){
+	String str = 
+		"public class Bar {\n" +
+		"  String s;\n" + 
+		"  /**/\n" + 
+		"}\n";
+
+	String testName = "";
+	String completeBehind = "/**/";
+	String expectedCompletionNodeToString = "<CompleteOnType:>";
+	String completionIdentifier = "";
+	String expectedReplacedSource = "";
+	int cursorLocation = str.lastIndexOf("/**/") + completeBehind.length() - 1;
+	String expectedUnitDisplayString =
+		"public class Bar {\n" + 
+		"  String s;\n" + 
+		"  <CompleteOnType:>;\n" + 
+		"  public Bar() {\n" + 
+		"  }\n" + 
+		"}\n";
+
+	checkDietParse(
+		str.toCharArray(), 
+		cursorLocation, 
+		expectedCompletionNodeToString,
+		expectedUnitDisplayString,
+		completionIdentifier,
+		expectedReplacedSource,
+		testName); 
+}
 }
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/CompletionRecoveryTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/CompletionRecoveryTest.java
index 735ae33..8911f66 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/CompletionRecoveryTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/CompletionRecoveryTest.java
@@ -625,7 +625,7 @@
 		"  }\n" + 
 		"}\n",
 		// expectedCompletionIdentifier:
-		NONE,
+		"",
 		// expectedReplacedSource:
 		NONE,
 		// test name
@@ -656,7 +656,7 @@
 		"  }\n" + 
 		"}\n",
 		// expectedCompletionIdentifier:
-		NONE,
+		"",
 		// expectedReplacedSource:
 		NONE,
 		// test name
diff --git a/org.eclipse.jdt.core/buildnotes_jdt-core.html b/org.eclipse.jdt.core/buildnotes_jdt-core.html
index d3df2c3..c081cb9 100644
--- a/org.eclipse.jdt.core/buildnotes_jdt-core.html
+++ b/org.eclipse.jdt.core/buildnotes_jdt-core.html
@@ -57,7 +57,9 @@
 </ul>
 
 <h3>Problem Reports Fixed</h3>
-<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84750">84750</a>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=116419">116419</a>
+code assist regression: POTENTIAL_METHOD_DECLARATION not offered anymore
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=84750">84750</a>
 [perf] BinaryMethod.getParameterNames does not follow IMethod API contract
 <br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110650">110650</a>
 Need API for determining Java line delimiter
@@ -170,8 +172,6 @@
 annotations only applied to first field in a declaration
 <br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=112843">112843</a>
 Cut blocked by background build
-<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=114115">114115</a>
-[assist] completionIdentifier should be set while reading next token instead of getting current identifier source
 <br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=116028">116028</a>
 annotations only applied to first field in a declaration
 <br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=110797">110797</a>
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionJavadocParser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionJavadocParser.java
index d59f949..48c4241 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionJavadocParser.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionJavadocParser.java
@@ -73,10 +73,6 @@
 				System.out.println("COMPLETION in Javadoc:"); //$NON-NLS-1$
 			}
 			completionScanner.completionIdentifier = null;
-			completionScanner.completedTokenFound = false;
-			completionScanner.completedIdentifierStart = 0;
-			completionScanner.completedIdentifierEnd = -1;
-			completionScanner.whitespacesBeforeCompletedTokenFound = false;
 			this.firstTagPosition = 1;
 			super.checkDeprecation(commentPtr);
 		} else {
@@ -461,7 +457,14 @@
 			char[] name = null;
 			CompletionScanner completionScanner = (CompletionScanner) this.scanner;
 			boolean isTypeParam = false;
-			if (this.identifierPtr >= 0) {
+			if (this.identifierPtr < 0) {
+				// workaround, empty token should set an empty identifier by scanner and so identifierPtr should be == 0
+				if (completionScanner.getCurrentIdentifierSource() == CompletionScanner.EmptyCompletionIdentifier) {
+					namePosition = completionScanner.completedIdentifierStart;
+					startPosition = completionScanner.completedIdentifierStart;
+					endPosition = completionScanner.completedIdentifierEnd;
+				}
+			} else {
 				char[] identifier = null;
 				switch (this.identifierPtr) {
 					case 2:
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java
index de19416..b831619 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java
@@ -3279,10 +3279,6 @@
 	this.cursorLocation = cursorLoc;
 	CompletionScanner completionScanner = (CompletionScanner)this.scanner;
 	completionScanner.completionIdentifier = null;
-	completionScanner.completedTokenFound = false;
-	completionScanner.completedIdentifierStart = 0;
-	completionScanner.completedIdentifierEnd = -1;
-	completionScanner.whitespacesBeforeCompletedTokenFound = false;
 	completionScanner.cursorLocation = cursorLoc;
 	return this.dietParse(sourceUnit, compilationResult);
 }
@@ -3471,28 +3467,11 @@
 	}
 	return false;
 }
-protected boolean moveRecoveryCheckpoint() {
-	CompletionScanner completionScanner = (CompletionScanner)this.scanner;
-	boolean completedTokenFound = completionScanner.completedTokenFound;
-	int start = completionScanner.completedIdentifierStart;
-	int end = completionScanner.completedIdentifierEnd;
-	boolean whitespacesAlreadyProposed = completionScanner.whitespacesBeforeCompletedTokenFound;
-	boolean result = super.moveRecoveryCheckpoint();
-	completionScanner.completedTokenFound = completedTokenFound;
-	completionScanner.completedIdentifierStart = start;
-	completionScanner.completedIdentifierEnd = end;
-	completionScanner.whitespacesBeforeCompletedTokenFound = whitespacesAlreadyProposed;
-	return result;
-}
 public CompilationUnitDeclaration parse(ICompilationUnit sourceUnit, CompilationResult compilationResult, int cursorLoc) {
 
 	this.cursorLocation = cursorLoc;
 	CompletionScanner completionScanner = (CompletionScanner)this.scanner;
 	completionScanner.completionIdentifier = null;
-	completionScanner.completedTokenFound = false;
-	completionScanner.completedIdentifierStart = 0;
-	completionScanner.completedIdentifierEnd = -1;
-	completionScanner.whitespacesBeforeCompletedTokenFound = false;
 	completionScanner.cursorLocation = cursorLoc;
 	return this.parse(sourceUnit, compilationResult);
 }
@@ -3678,12 +3657,7 @@
 	return super.resumeAfterRecovery();
 }
 public void setAssistIdentifier(char[] assistIdent){
-	CompletionScanner completionScanner = (CompletionScanner)scanner;
-	completionScanner.completionIdentifier = assistIdent;
-	if(assistIdent == null) {
-		completionScanner.completedTokenFound = false;
-		completionScanner.whitespacesBeforeCompletedTokenFound = false;
-	}
+	((CompletionScanner)scanner).completionIdentifier = assistIdent;
 }
 public  String toString() {
 	String s = ""; //$NON-NLS-1$
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 6683fc5..ec6e0d8 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
@@ -36,9 +36,6 @@
 	public int completedIdentifierStart = 0;
 	public int completedIdentifierEnd = -1;
 	public int unicodeCharSize;
-	
-	public boolean whitespacesBeforeCompletedTokenFound = false;
-	public boolean completedTokenFound = false;
 
 	public static final char[] EmptyCompletionIdentifier = {};
 	
@@ -137,12 +134,9 @@
 					}
 					if (this.currentPosition > this.eofPosition) {
 						/* might be completing at eof (e.g. behind a dot) */
-						if (!this.completedTokenFound && 
+						if (this.completionIdentifier == null && 
 							this.startPosition == this.cursorLocation + 1){
 							this.currentPosition = this.startPosition; // for being detected as empty free identifier
-							this.completedTokenFound = true;
-							this.completedIdentifierStart = this.startPosition;
-							this.completedIdentifierEnd = this.currentPosition - 1;
 							return TokenNameIdentifier;
 						}	
 						return TokenNameEOF;
@@ -167,24 +161,12 @@
 				}
 				/* completion requesting strictly inside blanks */
 				if ((whiteStart != this.currentPosition)
-						//&& (previousToken == TokenNameDOT)
-						&& (!this.completedTokenFound)
-						&& (whiteStart <= this.cursorLocation+1)
-						&& (this.cursorLocation < this.startPosition)
-						&& !Character.isJavaIdentifierStart(this.currentCharacter)){
-
-					if (this.tokenizeWhiteSpace && hasWhiteSpaces && !this.whitespacesBeforeCompletedTokenFound) {
-						// reposition scanner in case we are interested by spaces as tokens
-						this.currentPosition-=offset;
-						this.startPosition = whiteStart;
-						this.whitespacesBeforeCompletedTokenFound = true;
-						return TokenNameWHITESPACE;
-					}
+					//&& (previousToken == TokenNameDOT)
+					&& (this.completionIdentifier == null)
+					&& (whiteStart <= this.cursorLocation+1)
+					&& (this.cursorLocation < this.startPosition)
+					&& !Character.isJavaIdentifierStart(this.currentCharacter)){
 					this.currentPosition = this.startPosition; // for next token read
-					this.completedTokenFound = true;
-					this.completedIdentifierStart = this.startPosition;
-					this.completedIdentifierEnd = this.currentPosition - 1;
-					this.whitespacesBeforeCompletedTokenFound = false;
 					return TokenNameIdentifier;
 				}
 			} while (isWhiteSpace);
@@ -197,7 +179,7 @@
 			//little trick to get out in the middle of a source computation
 			if (this.currentPosition > this.eofPosition){
 				/* might be completing at eof (e.g. behind a dot) */
-				if (!this.completedTokenFound  && 
+				if (this.completionIdentifier == null && 
 					this.startPosition == this.cursorLocation + 1){
 					// compute end of empty identifier.
 					// if the empty identifier is at the start of a next token the end of
@@ -205,9 +187,6 @@
 				 	while(getNextCharAsJavaIdentifierPart()){/*empty*/}
 				 	this.endOfEmptyToken = this.currentPosition - 1;
 					this.currentPosition = this.startPosition; // for being detected as empty free identifier
-					this.completedTokenFound = true;
-					this.completedIdentifierStart = this.startPosition;
-					this.completedIdentifierEnd = this.currentPosition - 1;
 					return TokenNameIdentifier;
 				}				
 				return TokenNameEOF;
@@ -457,9 +436,6 @@
 											&& this.cursorLocation <= this.currentPosition-1) {
 										this.currentPosition = start;
 										// complete inside a string literal
-										this.completedTokenFound = true;
-										this.completedIdentifierStart = this.startPosition;
-										this.completedIdentifierEnd = this.currentPosition - 1;
 										return TokenNameStringLiteral;
 									}
 									start = this.currentPosition;
@@ -487,9 +463,6 @@
 									if(this.startPosition <= this.cursorLocation
 											&& this.cursorLocation <= this.currentPosition-1) {
 										// complete inside a string literal
-										this.completedTokenFound = true;
-										this.completedIdentifierStart = this.startPosition;
-										this.completedIdentifierEnd = this.currentPosition - 1;
 										return TokenNameStringLiteral;
 									}
 								}
@@ -539,9 +512,6 @@
 						if(this.startPosition <= this.cursorLocation
 							&& this.cursorLocation < this.currentPosition) {
 							// complete inside a string literal
-							this.completedTokenFound = true;
-							this.completedIdentifierStart = this.startPosition;
-							this.completedIdentifierEnd = this.currentPosition - 1;
 							return TokenNameStringLiteral;
 						}
 						throw new InvalidInputException(UNTERMINATED_STRING);
@@ -562,11 +532,6 @@
 						}
 						throw e; // rethrow
 					}
-					if (this.startPosition <= this.cursorLocation && this.cursorLocation <= this.currentPosition-1){
-						this.completedTokenFound = true;
-						this.completedIdentifierStart = this.startPosition;
-						this.completedIdentifierEnd = this.currentPosition - 1;
-					}
 					return TokenNameStringLiteral;
 				case '/' :
 					{
@@ -824,12 +789,9 @@
 		}
 	}
 	/* might be completing at very end of file (e.g. behind a dot) */
-	if (!this.completedTokenFound && 
+	if (this.completionIdentifier == null && 
 		this.startPosition == this.cursorLocation + 1){
 		this.currentPosition = this.startPosition; // for being detected as empty free identifier
-		this.completedTokenFound = true;
-		this.completedIdentifierStart = this.startPosition;
-		this.completedIdentifierEnd = this.currentPosition - 1;
 		return TokenNameIdentifier;
 	}
 	return TokenNameEOF;
@@ -844,14 +806,6 @@
 		throw new InvalidCursorLocation(InvalidCursorLocation.NO_COMPLETION_INSIDE_UNICODE);
 	}
 }
-public void resetTo(int begin, int end) {
-	super.resetTo(begin, end);
-	if(this.completedTokenFound && this.completedIdentifierStart >= begin) {
-		this.completedTokenFound = false;
-		this.whitespacesBeforeCompletedTokenFound = false;
-	}
-}
-
 ///*
 // * In case we actually read a keyword, but the cursor is located inside,
 // * we pretend we read an identifier.
@@ -861,17 +815,10 @@
 	int id = super.scanIdentifierOrKeyword();
 
 	// convert completed keyword into an identifier
-	if (this.startPosition <= this.cursorLocation+1 
+	if (id != TokenNameIdentifier
+		&& this.startPosition <= this.cursorLocation+1 
 		&& this.cursorLocation < this.currentPosition){
-		if(!this.completedTokenFound) {
-			this.completedTokenFound = true;
-			this.completedIdentifierStart = this.startPosition;
-			this.completedIdentifierEnd = this.currentPosition - 1;
-			return TokenNameIdentifier;
-		} else if(this.completedIdentifierStart == this.startPosition
-				&& this.completedIdentifierEnd == this.currentPosition - 1) {
-				return TokenNameIdentifier;
-		}
+		return TokenNameIdentifier;
 	}
 	return id;
 }