diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java
new file mode 100644
index 0000000..e206e5b
--- /dev/null
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java
@@ -0,0 +1,1231 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.compiler.parser;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jdt.core.compiler.CharOperation;
+import org.eclipse.jdt.core.compiler.InvalidInputException;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+
+/**
+ * Parser specialized for decoding javadoc comments
+ */
+public abstract class AbstractCommentParser {
+
+	// recognized tags
+	public static final char[] TAG_DEPRECATED = "deprecated".toCharArray(); //$NON-NLS-1$
+	public static final char[] TAG_PARAM = "param".toCharArray(); //$NON-NLS-1$
+	public static final char[] TAG_RETURN = "return".toCharArray(); //$NON-NLS-1$
+	public static final char[] TAG_THROWS = "throws".toCharArray(); //$NON-NLS-1$
+	public static final char[] TAG_EXCEPTION = "exception".toCharArray(); //$NON-NLS-1$
+	public static final char[] TAG_SEE = "see".toCharArray(); //$NON-NLS-1$
+	public static final char[] TAG_LINK = "link".toCharArray(); //$NON-NLS-1$
+	public static final char[] TAG_LINKPLAIN = "linkplain".toCharArray(); //$NON-NLS-1$
+	public static final char[] TAG_INHERITDOC = "inheritDoc".toCharArray(); //$NON-NLS-1$
+	
+	// tags expected positions
+	public final static int ORDERED_TAGS_NUMBER = 3;
+	public final static int PARAM_TAG_EXPECTED_ORDER = 0;
+	public final static int THROWS_TAG_EXPECTED_ORDER = 1;
+	public final static int SEE_TAG_EXPECTED_ORDER = 2;
+	
+	// Kind of comment parser
+	public final static int COMPIL_PARSER = 0x00000001;
+	public final static int DOM_PARSER = 0x00000002;
+	
+	// Public fields
+	public Scanner scanner;
+	public boolean checkDocComment = false;
+	
+	// Protected fields
+	protected boolean inherited, deprecated;
+	protected char[] source;
+	protected int index, endComment, lineEnd;
+	protected int tokenPreviousPosition;
+	protected int textStart, memberStart;
+	protected int tagSourceStart, tagSourceEnd;
+	protected int inlineTagStart;
+	protected Parser sourceParser;
+	protected Object returnStatement;
+	protected boolean lineStarted = false, inlineTagStarted = false;
+	protected int kind;
+	protected int[] lineEnds;
+	
+	// Private fields
+	private int currentTokenType = -1;
+	
+	// Line pointers
+	private int linePtr, lastLinePtr;
+	
+	// Identifier stack
+	protected int identifierPtr;
+	protected char[][] identifierStack;
+	protected int identifierLengthPtr;
+	protected int[] identifierLengthStack;
+	protected long[] identifierPositionStack;
+	// Ast stack
+	protected static int AstStackIncrement = 10;
+	protected int astPtr;
+	protected Object[] astStack;
+	protected int astLengthPtr;
+	protected int[] astLengthStack;
+
+	protected AbstractCommentParser(Parser sourceParser) {
+		this.sourceParser = sourceParser;
+		this.scanner = new Scanner(false, false, false, ClassFileConstants.JDK1_3, null, null, true/*taskCaseSensitive*/);
+		this.identifierStack = new char[20][];
+		this.identifierPositionStack = new long[20];
+		this.identifierLengthStack = new int[10];
+		this.astStack = new Object[30];
+		this.astLengthStack = new int[20];
+	}
+
+	/* (non-Javadoc)
+	 * Returns true if tag @deprecated is present in javadoc comment.
+	 * 
+	 * If javadoc checking is enabled, will also construct an Javadoc node, which will be stored into Parser.javadoc
+	 * slot for being consumed later on.
+	 */
+	protected boolean parseComment(int javadocStart, int javadocEnd) {
+
+		boolean validComment = true;
+		try {
+			// Init scanner position
+			this.scanner.resetTo(javadocStart, javadocEnd);
+			this.endComment = javadocEnd;
+			this.index = javadocStart;
+			readChar(); // starting '/'
+			int previousPosition = this.index;
+			readChar(); // first '*'
+			char nextCharacter= readChar(); // second '*'
+			
+			// Init local variables
+			this.astLengthPtr = -1;
+			this.astPtr = -1;
+			this.currentTokenType = -1;
+			this.inlineTagStarted = false;
+			this.inlineTagStart = -1;
+			this.lineStarted = false;
+			this.returnStatement = null;
+			this.inherited = false;
+			this.deprecated = false;
+			this.linePtr = getLineNumber(javadocStart);
+			this.lastLinePtr = getLineNumber(javadocEnd);
+			this.lineEnd = (this.linePtr == this.lastLinePtr) ? this.endComment : getLineEnd(this.linePtr);
+			this.textStart = -1;
+			char previousChar = 0;
+			int invalidTagLineEnd = -1;
+			int invalidInlineTagLineEnd = -1;
+			
+			// Loop on each comment character
+			while (this.index < this.endComment) {
+				previousPosition = this.index;
+				previousChar = nextCharacter;
+				
+				// Calculate line end (cannot use this.scanner.linePtr as scanner does not parse line ends again)
+				if (this.index > (this.lineEnd+1)) {
+					updateLineEnd();
+				}
+				
+				// Read next char only if token was consumed
+				if (this.currentTokenType < 0) {
+					nextCharacter = readChar(); // consider unicodes
+				} else {
+					previousPosition = this.scanner.getCurrentTokenStartPosition();
+					switch (this.currentTokenType) {
+						case TerminalTokens.TokenNameRBRACE:
+							nextCharacter = '}';
+							break;
+						case TerminalTokens.TokenNameMULTIPLY:
+							nextCharacter = '*';
+							break;
+					default:
+							nextCharacter = this.scanner.currentCharacter;
+					}
+					consumeToken();
+				}
+			
+				if (this.index >= this.endComment) {
+					break;
+				}
+				
+				switch (nextCharacter) {
+					case '@' :
+						boolean valid = false;
+						// Start tag parsing only if we have a java identifier start character and if we are on line beginning or at inline tag beginning
+						if ((!this.lineStarted || previousChar == '{')) {
+							this.lineStarted = true;
+							if (this.inlineTagStarted) {
+								this.inlineTagStarted = false;
+								// bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=53279
+								// Cannot have @ inside inline comment
+								if (this.sourceParser != null) {
+									int end = previousPosition<invalidInlineTagLineEnd ? previousPosition : invalidInlineTagLineEnd;
+									this.sourceParser.problemReporter().javadocUnterminatedInlineTag(this.inlineTagStart, end);
+								}
+								validComment = false;
+								if (this.lineStarted && this.textStart != -1 && this.textStart < previousPosition) {
+									pushText(this.textStart, previousPosition);
+								}
+								if (this.kind == DOM_PARSER) refreshInlineTagPosition(previousPosition);
+							}
+							if (previousChar == '{') {
+								if (this.textStart != -1 && this.textStart < this.inlineTagStart) {
+									pushText(this.textStart, this.inlineTagStart);
+								}
+								this.inlineTagStarted = true;
+								invalidInlineTagLineEnd = this.lineEnd;
+							} else if (this.textStart != -1 && this.textStart < invalidTagLineEnd) {
+								pushText(this.textStart, invalidTagLineEnd);
+							}
+							this.scanner.resetTo(this.index, this.endComment);
+							this.currentTokenType = -1; // flush token cache at line begin
+							try {
+								int token = readTokenAndConsume();
+								this.tagSourceStart = this.scanner.getCurrentTokenStartPosition();
+								this.tagSourceEnd = this.scanner.getCurrentTokenEndPosition();
+								char[] tag = this.scanner.getCurrentIdentifierSource(); // first token is either an identifier or a keyword
+								if (this.kind == DOM_PARSER) {
+									// For DOM parser, try to get tag name other than java identifier
+									// (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=51660)
+									int tk = token;
+									int le = this.lineEnd;
+									char pc = peekChar();
+									tagNameToken: while (tk != TerminalTokens.TokenNameEOF) {
+										this.tagSourceEnd = this.scanner.getCurrentTokenEndPosition();
+										token = tk;
+										// !, ", #, %, &, ', -, :, <, >, * chars and spaces are not allowed in tag names
+										switch (pc) {
+											case '}':
+											case '!':
+											case '#':
+											case '%':
+											case '&':
+											case '\'':
+											case ':':
+											case '-':
+											case '<':
+											case '>':
+											case '*': // break for '*' as this is perhaps the end of comment (bug 65288)
+												break tagNameToken;
+											default:
+												if (pc == ' ' || Character.isWhitespace(pc)) break tagNameToken;
+										}
+										tk = readTokenAndConsume();
+										pc = peekChar();
+									}
+									int length = this.tagSourceEnd-this.tagSourceStart+1;
+									tag = new char[length];
+									System.arraycopy(this.source, this.tagSourceStart, tag, 0, length);
+									this.index = this.tagSourceEnd+1;
+									this.scanner.currentPosition = this.tagSourceEnd+1;
+									this.tagSourceStart = previousPosition;
+									this.lineEnd = le;
+								}
+								switch (token) {
+									case TerminalTokens.TokenNameIdentifier :
+										if (CharOperation.equals(tag, TAG_DEPRECATED)) {
+											this.deprecated = true;
+											if (this.kind == DOM_PARSER) {
+												valid = parseTag();
+											} else {
+												valid = true;
+											}
+										} else if (CharOperation.equals(tag, TAG_INHERITDOC)) {
+											// inhibits inherited flag when tags have been already stored
+											// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=51606
+											// Note that for DOM_PARSER, nodes stack may be not empty even no '@' tag
+											// was encountered in comment. But it cannot be the case for COMPILER_PARSER
+											// and so is enough as it is only this parser which signals the missing tag warnings...
+											this.inherited = this.astPtr==-1;
+											if (this.kind == DOM_PARSER) {
+												valid = parseTag();
+											} else {
+												valid = true;
+											}
+										} else if (CharOperation.equals(tag, TAG_PARAM)) {
+											valid = parseParam();
+										} else if (CharOperation.equals(tag, TAG_EXCEPTION)) {
+											valid = parseThrows(false);
+										} else if (CharOperation.equals(tag, TAG_SEE)) {
+											if (this.inlineTagStarted) {
+												// bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=53290
+												// Cannot have @see inside inline comment
+												valid = false;
+												if (this.sourceParser != null)
+													this.sourceParser.problemReporter().javadocUnexpectedTag(this.tagSourceStart, this.tagSourceEnd);
+											} else {
+												valid = parseSee(false);
+											}
+										} else if (CharOperation.equals(tag, TAG_LINK)) {
+											if (this.inlineTagStarted) {
+												valid = parseSee(false);
+											} else {
+												// bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=53290
+												// Cannot have @link outside inline comment
+												valid = false;
+												if (this.sourceParser != null)
+													this.sourceParser.problemReporter().javadocUnexpectedTag(this.tagSourceStart, this.tagSourceEnd);
+											}
+										} else if (CharOperation.equals(tag, TAG_LINKPLAIN)) {
+											if (this.inlineTagStarted) {
+												valid = parseSee(true);
+											} else {
+												valid = parseTag();
+											}
+										} else {
+											valid = parseTag();
+										}
+										break;
+									case TerminalTokens.TokenNamereturn :
+										valid = parseReturn();
+										break;
+									case TerminalTokens.TokenNamethrows :
+										valid = parseThrows(true);
+										break;
+									default:
+										if (this.kind == DOM_PARSER) {
+											switch (token) {
+												case TerminalTokens.TokenNameabstract:
+												case TerminalTokens.TokenNameassert:
+												case TerminalTokens.TokenNameboolean:
+												case TerminalTokens.TokenNamebreak:
+												case TerminalTokens.TokenNamebyte:
+												case TerminalTokens.TokenNamecase:
+												case TerminalTokens.TokenNamecatch:
+												case TerminalTokens.TokenNamechar:
+												case TerminalTokens.TokenNameclass:
+												case TerminalTokens.TokenNamecontinue:
+												case TerminalTokens.TokenNamedefault:
+												case TerminalTokens.TokenNamedo:
+												case TerminalTokens.TokenNamedouble:
+												case TerminalTokens.TokenNameelse:
+												case TerminalTokens.TokenNameextends:
+												case TerminalTokens.TokenNamefalse:
+												case TerminalTokens.TokenNamefinal:
+												case TerminalTokens.TokenNamefinally:
+												case TerminalTokens.TokenNamefloat:
+												case TerminalTokens.TokenNamefor:
+												case TerminalTokens.TokenNameif:
+												case TerminalTokens.TokenNameimplements:
+												case TerminalTokens.TokenNameimport:
+												case TerminalTokens.TokenNameinstanceof:
+												case TerminalTokens.TokenNameint:
+												case TerminalTokens.TokenNameinterface:
+												case TerminalTokens.TokenNamelong:
+												case TerminalTokens.TokenNamenative:
+												case TerminalTokens.TokenNamenew:
+												case TerminalTokens.TokenNamenull:
+												case TerminalTokens.TokenNamepackage:
+												case TerminalTokens.TokenNameprivate:
+												case TerminalTokens.TokenNameprotected:
+												case TerminalTokens.TokenNamepublic:
+												case TerminalTokens.TokenNameshort:
+												case TerminalTokens.TokenNamestatic:
+												case TerminalTokens.TokenNamestrictfp:
+												case TerminalTokens.TokenNamesuper:
+												case TerminalTokens.TokenNameswitch:
+												case TerminalTokens.TokenNamesynchronized:
+												case TerminalTokens.TokenNamethis:
+												case TerminalTokens.TokenNamethrow:
+												case TerminalTokens.TokenNametransient:
+												case TerminalTokens.TokenNametrue:
+												case TerminalTokens.TokenNametry:
+												case TerminalTokens.TokenNamevoid:
+												case TerminalTokens.TokenNamevolatile:
+												case TerminalTokens.TokenNamewhile:
+													valid = parseTag();
+													break;
+											}
+										}
+								}
+								this.textStart = this.index;
+								if (!valid) {
+									// bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=51600
+									// do not stop the inline tag when error is encountered to get text after
+									validComment = false;
+									// bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=51600
+									// for DOM AST node, store tag as text in case of invalid syntax
+									if (this.kind == DOM_PARSER) {
+										parseTag();
+										this.textStart = this.tagSourceEnd+1;
+										invalidTagLineEnd  = this.lineEnd;
+									}
+								}
+							} catch (InvalidInputException e) {
+								consumeToken();
+							}
+						}
+						break;
+					case '\r':
+					case '\n':
+						if (this.lineStarted && this.textStart < previousPosition) {
+							pushText(this.textStart, previousPosition);
+						}
+						this.lineStarted = false;
+						// Fix bug 51650
+						this.textStart = -1;
+						break;
+					case '}' :
+						if (this.inlineTagStarted) {
+							if (this.lineStarted && this.textStart != -1 && this.textStart < previousPosition) {
+								pushText(this.textStart, previousPosition);
+							}
+							if (this.kind == DOM_PARSER) refreshInlineTagPosition(previousPosition);
+							this.textStart = this.index;
+							this.inlineTagStarted = false;
+						} else {
+							if (!this.lineStarted) {
+								this.textStart = previousPosition;
+							}
+						}
+						this.lineStarted = true;
+						break;
+					case '{' :
+						if (this.inlineTagStarted) {
+							this.inlineTagStarted = false;
+							// bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=53279
+							// Cannot have opening brace in inline comment
+							if (this.sourceParser != null) {
+								int end = previousPosition<invalidInlineTagLineEnd ? previousPosition : invalidInlineTagLineEnd;
+								this.sourceParser.problemReporter().javadocUnterminatedInlineTag(this.inlineTagStart, end);
+							}
+							if (this.lineStarted && this.textStart != -1 && this.textStart < previousPosition) {
+								pushText(this.textStart, previousPosition);
+							}
+							if (this.kind == DOM_PARSER) refreshInlineTagPosition(previousPosition);
+						}
+						if (!this.lineStarted) {
+							this.textStart = previousPosition;
+						}
+						this.lineStarted = true;
+						this.inlineTagStart = previousPosition;
+						break;
+					case '*' :
+						// do nothing for '*' character
+						break;
+					default :
+						if (!CharOperation.isWhitespace(nextCharacter)) {
+							if (!this.lineStarted) {
+								this.textStart = previousPosition;
+							}
+							this.lineStarted = true;
+						}
+				}
+			}
+			// bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=53279
+			// Cannot leave comment inside inline comment
+			if (this.inlineTagStarted) {
+				this.inlineTagStarted = false;
+				if (this.sourceParser != null) {
+					int end = previousPosition<invalidInlineTagLineEnd ? previousPosition : invalidInlineTagLineEnd;
+					if (this.index >= this.endComment) end = invalidInlineTagLineEnd;
+					this.sourceParser.problemReporter().javadocUnterminatedInlineTag(this.inlineTagStart, end);
+				}
+				if (this.lineStarted && this.textStart != -1 && this.textStart < previousPosition) {
+					pushText(this.textStart, previousPosition);
+				}
+				if (this.kind == DOM_PARSER) {
+					refreshInlineTagPosition(previousPosition);
+				}
+			} else if (this.lineStarted && this.textStart < previousPosition) {
+				pushText(this.textStart, previousPosition);
+			}
+			updateDocComment();
+		} catch (Exception ex) {
+			validComment = false;
+		}
+		return validComment;
+	}
+
+	private void consumeToken() {
+		this.currentTokenType = -1; // flush token cache
+		updateLineEnd();
+	}
+
+	protected abstract Object createArgumentReference(char[] name, int dim, Object typeRef, long[] dimPos, long argNamePos) throws InvalidInputException;
+	protected abstract Object createFieldReference(Object receiver) throws InvalidInputException;
+	protected abstract Object createMethodReference(Object receiver, List arguments) throws InvalidInputException;
+	protected Object createReturnStatement() { return null; }
+	protected abstract Object createTypeReference(int primitiveToken);
+	
+	private int getEndPosition() {
+		if (this.scanner.getCurrentTokenEndPosition() > this.lineEnd) {
+			return this.lineEnd;
+		} else {
+			return this.scanner.getCurrentTokenEndPosition();
+		}
+	}
+
+	/*
+	 * Parse argument in @see tag method reference
+	 */
+	private Object parseArguments(Object receiver) throws InvalidInputException {
+
+		// Init
+		int modulo = 0; // should be 2 for (Type,Type,...) or 3 for (Type arg,Type arg,...)
+		int iToken = 0;
+		char[] argName = null;
+		List arguments = new ArrayList(10);
+		int start = this.scanner.getCurrentTokenStartPosition();
+		
+		// Parse arguments declaration if method reference
+		nextArg : while (this.index < this.scanner.eofPosition) {
+
+			// Read argument type reference
+			Object typeRef;
+			try {
+				typeRef = parseQualifiedName(false);
+			} catch (InvalidInputException e) {
+				break nextArg;
+			}
+			boolean firstArg = modulo == 0;
+			if (firstArg) { // verify position
+				if (iToken != 0)
+					break nextArg;
+			} else if ((iToken % modulo) != 0) {
+					break nextArg;
+			}
+			if (typeRef == null) {
+				if (firstArg && this.currentTokenType == TerminalTokens.TokenNameRPAREN) {
+					char pc = peekChar();
+					if (!Character.isWhitespace(pc) && (!this.inlineTagStarted || pc != '}')) {
+						if (this.sourceParser != null) this.sourceParser.problemReporter().javadocMalformedSeeReference(start, this.lineEnd);
+						return null;
+					}
+					this.lineStarted = true;
+					return createMethodReference(receiver, null);
+				}
+				break nextArg;
+			}
+			iToken++;
+
+			// Read possible array declaration
+			int dim = 0;
+			long[] dimPositions = new long[20]; // assume that there won't be more than 20 dimensions...
+			if (readToken() == TerminalTokens.TokenNameLBRACKET) {
+				int dimStart = this.scanner.getCurrentTokenStartPosition();
+				while (readToken() == TerminalTokens.TokenNameLBRACKET) {
+					consumeToken();
+					if (readToken() != TerminalTokens.TokenNameRBRACKET) {
+						break nextArg;
+					}
+					consumeToken();
+					dimPositions[dim++] = (((long) dimStart) << 32) + this.scanner.getCurrentTokenEndPosition();
+				}
+			}
+
+			// Read argument name
+			long argNamePos = -1;
+			if (readToken() == TerminalTokens.TokenNameIdentifier) {
+				consumeToken();
+				if (firstArg) { // verify position
+					if (iToken != 1)
+						break nextArg;
+				} else if ((iToken % modulo) != 1) {
+						break nextArg;
+				}
+				if (argName == null) { // verify that all arguments name are declared
+					if (!firstArg) {
+						break nextArg;
+					}
+				}
+				argName = this.scanner.getCurrentIdentifierSource();
+				argNamePos = (((long)this.scanner.getCurrentTokenStartPosition())<<32)+this.scanner.getCurrentTokenEndPosition();
+				iToken++;
+			} else if (argName != null) { // verify that no argument name is declared
+				break nextArg;
+			}
+			
+			// Verify token position
+			if (firstArg) {
+				modulo = iToken + 1;
+			} else {
+				if ((iToken % modulo) != (modulo - 1)) {
+					break nextArg;
+				}
+			}
+
+			// Read separator or end arguments declaration
+			int token = readToken();
+			char[] name = argName == null ? new char[0] : argName;
+			if (token == TerminalTokens.TokenNameCOMMA) {
+				// Create new argument
+				Object argument = createArgumentReference(name, dim, typeRef, dimPositions, argNamePos);
+				arguments.add(argument);
+				consumeToken();
+				iToken++;
+			} else if (token == TerminalTokens.TokenNameRPAREN) {
+				char pc = peekChar();
+				if (!Character.isWhitespace(pc) && (!this.inlineTagStarted || pc != '}')) {
+					if (this.sourceParser != null) this.sourceParser.problemReporter().javadocMalformedSeeReference(start, this.lineEnd);
+					return null;
+				}
+				// Create new argument
+				Object argument = createArgumentReference(name, dim, typeRef, dimPositions, argNamePos);
+				arguments.add(argument);
+				consumeToken();
+				return createMethodReference(receiver, arguments);
+			} else {
+				break nextArg;
+			}
+		}
+
+		// Something wrong happened => Invalid input
+		throw new InvalidInputException();
+	}
+
+	/*
+	 * Parse an URL link reference in @see tag
+	 */
+	private boolean parseHref() throws InvalidInputException {
+		int start = this.scanner.getCurrentTokenStartPosition();
+		if (Character.toLowerCase(readChar()) == 'a') {
+			this.scanner.currentPosition = this.index;
+			if (readToken() == TerminalTokens.TokenNameIdentifier) {
+				this.currentTokenType = -1; // do not update line end
+				try {
+					if (CharOperation.equals(this.scanner.getCurrentIdentifierSource(), new char[]{'h', 'r', 'e', 'f'}, false) &&
+						readToken() == TerminalTokens.TokenNameEQUAL) {
+						this.currentTokenType = -1; // do not update line end
+						if (readToken() == TerminalTokens.TokenNameStringLiteral) {
+							this.currentTokenType = -1; // do not update line end
+							if (readToken() == TerminalTokens.TokenNameGREATER) {
+								consumeToken(); // update line end as new lines are allowed in URL description
+								while (readToken() != TerminalTokens.TokenNameLESS) {
+									if (this.scanner.currentPosition >= this.scanner.eofPosition || this.scanner.currentCharacter == '@') {
+										// Reset position: we want to rescan last token
+										this.index = this.tokenPreviousPosition;
+										this.scanner.currentPosition = this.tokenPreviousPosition;
+										this.currentTokenType = -1;
+										// Signal syntax error
+										if (this.sourceParser != null) this.sourceParser.problemReporter().javadocInvalidSeeUrlReference(start, this.lineEnd);
+										return false;
+									}
+									consumeToken();
+								}
+								this.currentTokenType = -1; // do not update line end
+								if (readChar() == '/') {
+									if (Character.toLowerCase(readChar()) == 'a') {
+										if (readChar() == '>') {
+											// Valid href
+											return true;
+										}
+									}
+								}
+							}
+						}
+					}
+				} catch (InvalidInputException ex) {
+					// Do nothing as we want to keep positions for error message
+				}
+			}
+		}
+		// Reset position: we want to rescan last token
+		this.index = this.tokenPreviousPosition;
+		this.scanner.currentPosition = this.tokenPreviousPosition;
+		this.currentTokenType = -1;
+		// Signal syntax error
+		if (this.sourceParser != null) this.sourceParser.problemReporter().javadocInvalidSeeUrlReference(start, this.lineEnd);
+		return false;
+	}
+
+	/*
+	 * Parse a method reference in @see tag
+	 */
+	private Object parseMember(Object receiver) throws InvalidInputException {
+		// Init
+		this.identifierPtr = -1;
+		this.identifierLengthPtr = -1;
+		int start = this.scanner.getCurrentTokenStartPosition();
+		this.memberStart = start;
+
+		// Get member identifier
+		if (readToken() == TerminalTokens.TokenNameIdentifier) {
+			consumeToken();
+			pushIdentifier(true);
+			int previousPosition = this.index;
+			if (readToken() == TerminalTokens.TokenNameLPAREN) {
+				consumeToken();
+				start = this.scanner.getCurrentTokenStartPosition();
+				try {
+					return parseArguments(receiver);
+				} catch (InvalidInputException e) {
+					int end = this.scanner.getCurrentTokenEndPosition() < this.lineEnd ?
+							this.scanner.getCurrentTokenEndPosition() :
+							this.scanner.getCurrentTokenStartPosition();
+					end = end < this.lineEnd ? end : this.lineEnd;
+					if (this.sourceParser != null) this.sourceParser.problemReporter().javadocInvalidSeeReferenceArgs(start, end);
+				}
+				return null;
+			}
+			// Reset position: we want to rescan last token
+			if (this.currentTokenType != -1) {
+				this.index = previousPosition;
+				this.scanner.currentPosition = previousPosition;
+				this.currentTokenType = -1;
+			}
+			return createFieldReference(receiver);
+		}
+		int end = getEndPosition() - 1;
+		end = start > end ? getEndPosition() : end;
+		if (this.sourceParser != null) this.sourceParser.problemReporter().javadocInvalidSeeReference(start, end);
+		// Reset position: we want to rescan last token
+		this.index = this.tokenPreviousPosition;
+		this.scanner.currentPosition = this.tokenPreviousPosition;
+		this.currentTokenType = -1;
+		return null;
+	}
+
+	/*
+	 * Parse @param tag declaration
+	 */
+	protected boolean parseParam() {
+
+		// Store current token state
+		int start = this.tagSourceStart;
+		int end = this.tagSourceEnd;
+
+		try {
+			// Push identifier next
+			int token = readToken();
+			switch (token) {
+				case TerminalTokens.TokenNameIdentifier :
+					consumeToken();
+					return pushParamName();
+				case TerminalTokens.TokenNameEOF :
+					break;
+				default :
+					start = this.scanner.getCurrentTokenStartPosition();
+					end = getEndPosition();
+					if (end < start) start = this.tagSourceStart;
+					break;
+			}
+		} catch (InvalidInputException e) {
+			end = getEndPosition();
+		}
+
+		// Reset position to avoid missing tokens when new line was encountered
+		this.index = this.tokenPreviousPosition;
+		this.scanner.currentPosition = this.tokenPreviousPosition;
+		this.currentTokenType = -1;
+
+		// Report problem
+		if (this.sourceParser != null) this.sourceParser.problemReporter().javadocMissingParamName(start, end);
+		return false;
+	}
+
+	/*
+	 * Parse a qualified name and built a type reference if the syntax is valid.
+	 */
+	protected Object parseQualifiedName(boolean reset) throws InvalidInputException {
+
+		// Reset identifier stack if requested
+		if (reset) {
+			this.identifierPtr = -1;
+			this.identifierLengthPtr = -1;
+		}
+
+		// Scan tokens
+		int primitiveToken = -1;
+		nextToken : for (int iToken = 0; ; iToken++) {
+			int token = readToken();
+			switch (token) {
+				case TerminalTokens.TokenNameIdentifier :
+					if (((iToken % 2) > 0)) { // identifiers must be odd tokens
+						break nextToken;
+					}
+					pushIdentifier(iToken == 0);
+					consumeToken();
+					break;
+
+				case TerminalTokens.TokenNameDOT :
+					if ((iToken % 2) == 0) { // dots must be even tokens
+						throw new InvalidInputException();
+					}
+					consumeToken();
+					break;
+
+				case TerminalTokens.TokenNamevoid :
+				case TerminalTokens.TokenNameboolean :
+				case TerminalTokens.TokenNamebyte :
+				case TerminalTokens.TokenNamechar :
+				case TerminalTokens.TokenNamedouble :
+				case TerminalTokens.TokenNamefloat :
+				case TerminalTokens.TokenNameint :
+				case TerminalTokens.TokenNamelong :
+				case TerminalTokens.TokenNameshort :
+					if (iToken > 0) {
+						throw new InvalidInputException();
+					}
+					pushIdentifier(true);
+					primitiveToken = token;
+					consumeToken();
+					break nextToken;
+
+				default :
+					if (iToken == 0) {
+						return null;
+					}
+					if ((iToken % 2) == 0) { // cannot leave on a dot
+						// Reset position: we want to rescan last token
+						if (this.kind == DOM_PARSER && this.currentTokenType != -1) {
+							this.index = this.tokenPreviousPosition;
+							this.scanner.currentPosition = this.tokenPreviousPosition;
+							this.currentTokenType = -1;
+						}
+						throw new InvalidInputException();
+					}
+					break nextToken;
+			}
+		}
+		// Reset position: we want to rescan last token
+		if (this.currentTokenType != -1) {
+			this.index = this.tokenPreviousPosition;
+			this.scanner.currentPosition = this.tokenPreviousPosition;
+			this.currentTokenType = -1;
+		}
+		return createTypeReference(primitiveToken);
+	}
+
+	/*
+	 * Parse a reference in @see tag
+	 */
+	protected boolean parseReference(boolean plain) throws InvalidInputException {
+		Object typeRef = null;
+		Object reference = null;
+		int previousPosition = -1;
+		nextToken : while (this.index < this.scanner.eofPosition) {
+			previousPosition = this.index;
+			int token = readToken();
+			switch (token) {
+				case TerminalTokens.TokenNameStringLiteral :
+					// @see "string"
+					int start = this.scanner.getCurrentTokenStartPosition();
+					if (typeRef == null) {
+						consumeToken();
+						while (Character.isWhitespace(this.source[this.index])) {
+							if (this.source[this.index] == '\r' || this.source[this.index] == '\n') {
+								if (this.kind == DOM_PARSER) {
+									parseTag();
+									pushText(previousPosition, this.index);
+								}
+								return true;
+							}
+							this.index++;
+						}
+					}
+					if (this.sourceParser != null) this.sourceParser.problemReporter().javadocInvalidSeeReference(start, this.lineEnd);
+					return false;
+				case TerminalTokens.TokenNameLESS :
+					// @see "<a href="URL#Value">label</a>
+					consumeToken();
+					start = this.scanner.getCurrentTokenStartPosition();
+					if (parseHref()) {
+						if (typeRef == null) {
+							consumeToken();
+							while (Character.isWhitespace(this.source[this.index])) {
+								if (this.source[this.index] == '\r' || this.source[this.index] == '\n') {
+									if (this.kind == DOM_PARSER) {
+										parseTag();
+										pushText(previousPosition, this.index);
+									}
+									return true;
+								}
+								this.index++;
+							}
+						}
+						if (this.sourceParser != null) this.sourceParser.problemReporter().javadocInvalidSeeReference(start, this.lineEnd);
+					}
+					return false;
+				case TerminalTokens.TokenNameERROR :
+					if (this.scanner.currentCharacter == '#') { // @see ...#member
+						consumeToken();
+						reference = parseMember(typeRef);
+						if (reference != null) {
+							return pushSeeRef(reference, plain);
+						}
+						return false;
+					}
+					break nextToken;
+				case TerminalTokens.TokenNameIdentifier :
+					if (typeRef == null) {
+						typeRef = parseQualifiedName(true);
+						break;
+					}
+					break nextToken;
+				default :
+					break nextToken;
+			}
+		}
+		
+		// Verify that we got a reference
+		if (reference == null) reference = typeRef;
+		if (reference == null) {
+			this.index = this.tokenPreviousPosition;
+			this.scanner.currentPosition = this.tokenPreviousPosition;
+			this.currentTokenType = -1;
+			if (this.sourceParser != null) this.sourceParser.problemReporter().javadocMissingSeeReference(this.tagSourceStart, this.tagSourceEnd);
+			return false;
+		}
+
+		// Verify that line end does not start with an open parenthese (which could be a constructor reference wrongly written...)
+		// bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=47215
+		int start = this.scanner.getCurrentTokenStartPosition();
+		try {
+			int token = readToken();
+			if (token != TerminalTokens.TokenNameLPAREN) {
+				// Reset position: we want to rescan last token
+				if (this.currentTokenType != -1) {
+					this.index = this.tokenPreviousPosition;
+					this.scanner.currentPosition = this.tokenPreviousPosition;
+					this.currentTokenType = -1;
+				}
+				return pushSeeRef(reference, plain);
+			}
+		} catch (InvalidInputException e) {
+			// Do nothing as we report an error after
+		}
+		// Reset position to avoid missing tokens when new line was encountered
+		this.index = this.tokenPreviousPosition;
+		this.scanner.currentPosition = this.tokenPreviousPosition;
+		this.currentTokenType = -1;
+		if (this.sourceParser != null) this.sourceParser.problemReporter().javadocInvalidSeeReference(start, this.lineEnd);
+		return false;
+	}
+
+	/*
+	 * Parse @return tag declaration
+	 */
+	protected abstract boolean parseReturn();
+
+	/*
+	 * Parse @see tag declaration
+	 */
+	protected boolean parseSee(boolean plain) {
+		int start = this.scanner.currentPosition;
+		try {
+			return parseReference(plain);
+		} catch (InvalidInputException ex) {
+				if (this.sourceParser != null) this.sourceParser.problemReporter().javadocInvalidSeeReference(start, getEndPosition());
+		}
+		// Reset position to avoid missing tokens when new line was encountered
+		this.index = this.tokenPreviousPosition;
+		this.scanner.currentPosition = this.tokenPreviousPosition;
+		this.currentTokenType = -1;
+		return false;
+	}
+
+	/*
+	 * Parse @return tag declaration
+	 */
+	protected abstract boolean parseTag();
+
+	/*
+	 * Parse @throws tag declaration
+	 */
+	protected boolean parseThrows(boolean real) {
+		int start = this.scanner.currentPosition;
+		try {
+			Object typeRef = parseQualifiedName(true);
+			if (typeRef == null) {
+				if (this.sourceParser != null) this.sourceParser.problemReporter().javadocMissingThrowsClassName(this.tagSourceStart, this.tagSourceEnd);
+			} else {
+				return pushThrowName(typeRef, real);
+			}
+		} catch (InvalidInputException ex) {
+			if (this.sourceParser != null) this.sourceParser.problemReporter().javadocInvalidThrowsClass(start, getEndPosition());
+		}
+		return false;
+	}
+	
+	/*
+	 * push the consumeToken on the identifier stack. Increase the total number of identifier in the stack.
+	 */
+	protected void pushIdentifier(boolean newLength) {
+
+		int stackLength = this.identifierStack.length;
+		if (++this.identifierPtr >= stackLength) {
+			System.arraycopy(
+				this.identifierStack, 0,
+				this.identifierStack = new char[stackLength + 10][], 0,
+				stackLength);
+			System.arraycopy(
+				this.identifierPositionStack, 0,
+				this.identifierPositionStack = new long[stackLength + 10], 0,
+				stackLength);
+		}
+		this.identifierStack[this.identifierPtr] = this.scanner.getCurrentIdentifierSource();
+		this.identifierPositionStack[this.identifierPtr] = (((long) this.scanner.startPosition) << 32) + (this.scanner.currentPosition - 1);
+
+		if (newLength) {
+			stackLength = this.identifierLengthStack.length;
+			if (++this.identifierLengthPtr >= stackLength) {
+				System.arraycopy(
+					this.identifierLengthStack, 0,
+					this.identifierLengthStack = new int[stackLength + 10], 0,
+					stackLength);
+			}
+			this.identifierLengthStack[this.identifierLengthPtr] = 1;
+		} else {
+			this.identifierLengthStack[this.identifierLengthPtr]++;
+		}
+	}
+
+	/*
+	 * Add a new obj on top of the ast stack.
+	 * If new length is required, then add also a new length in length stack.
+	 */
+	protected void pushOnAstStack(Object node, boolean newLength) {
+
+		if (node == null) {
+			this.astLengthStack[++this.astLengthPtr] = 0;
+			return;
+		}
+
+		int stackLength = this.astStack.length;
+		if (++this.astPtr >= stackLength) {
+			System.arraycopy(
+				this.astStack, 0,
+				this.astStack = new Object[stackLength + AstStackIncrement], 0,
+				stackLength);
+			this.astPtr = stackLength;
+		}
+		this.astStack[this.astPtr] = node;
+
+		if (newLength) {
+			stackLength = this.astLengthStack.length;
+			if (++this.astLengthPtr >= stackLength) {
+				System.arraycopy(
+					this.astLengthStack, 0,
+					this.astLengthStack = new int[stackLength + AstStackIncrement], 0,
+					stackLength);
+			}
+			this.astLengthStack[this.astLengthPtr] = 1;
+		} else {
+			this.astLengthStack[this.astLengthPtr]++;
+		}
+	}
+
+	/*
+	 * Push a param name in ast node stack.
+	 */
+	protected abstract boolean pushParamName();
+
+	/*
+	 * Push a reference statement in ast node stack.
+	 */
+	protected abstract boolean pushSeeRef(Object statement, boolean plain);
+
+	protected abstract void pushText(int start, int end);
+	protected void refreshInlineTagPosition(int previousPosition) {
+		// do nothing by default
+	}
+
+	/*
+	 * Return current character without move index position.
+	 */
+	private char peekChar() {
+		int idx = this.index;
+		char c = this.source[idx++];
+		if (c == '\\' && this.source[idx] == 'u') {
+			int c1, c2, c3, c4;
+			idx++;
+			while (this.source[idx] == 'u')
+				idx++;
+			if (!(((c1 = Character.getNumericValue(this.source[idx++])) > 15 || c1 < 0)
+					|| ((c2 = Character.getNumericValue(this.source[idx++])) > 15 || c2 < 0)
+					|| ((c3 = Character.getNumericValue(this.source[idx++])) > 15 || c3 < 0) || ((c4 = Character.getNumericValue(this.source[idx++])) > 15 || c4 < 0))) {
+				c = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
+			}
+		}
+		return c;
+	}
+
+	/*
+	 * Push a throws type ref in ast node stack.
+	 */
+	protected abstract boolean pushThrowName(Object typeRef, boolean real);
+
+	/*
+	 * Read current character and move index position.
+	 * Warning: scanner position is unchanged using this method!
+	 */
+	protected char readChar() {
+	
+		char c = this.source[this.index++];
+		if (c == '\\' && this.source[this.index] == 'u') {
+			int c1, c2, c3, c4;
+			int pos = this.index;
+			this.index++;
+			while (this.source[this.index] == 'u')
+				this.index++;
+			if (!(((c1 = Character.getNumericValue(this.source[this.index++])) > 15 || c1 < 0)
+					|| ((c2 = Character.getNumericValue(this.source[this.index++])) > 15 || c2 < 0)
+					|| ((c3 = Character.getNumericValue(this.source[this.index++])) > 15 || c3 < 0) || ((c4 = Character.getNumericValue(this.source[this.index++])) > 15 || c4 < 0))) {
+				c = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4);
+			} else {
+				// TODO (frederic) currently reset to previous position, perhaps signal a syntax error would be more appropriate
+				this.index = pos;
+			}
+		}
+		return c;
+	}
+
+	/*
+	 * Read token only if previous was consumed
+	 */
+	private int readToken() throws InvalidInputException {
+		if (this.currentTokenType < 0) {
+			this.tokenPreviousPosition = this.scanner.currentPosition;
+			this.currentTokenType = this.scanner.getNextToken();
+			if (this.scanner.currentPosition > (this.lineEnd+1)) { // be sure to be on next line (lineEnd is still on the same line)
+				this.lineStarted = false;
+				while (this.currentTokenType == TerminalTokens.TokenNameMULTIPLY) {
+					this.currentTokenType = this.scanner.getNextToken();
+				}
+			}
+			this.index = this.scanner.currentPosition;
+			this.lineStarted = true; // after having read a token, line is obviously started...
+		}
+		return this.currentTokenType;
+	}
+
+	private int readTokenAndConsume() throws InvalidInputException {
+		int token = readToken();
+		consumeToken();
+		return token;
+	}
+
+	public String toString() {
+		StringBuffer buffer = new StringBuffer();
+		int startPos = this.scanner.currentPosition<this.index ? this.scanner.currentPosition : this.index;
+		int endPos = this.scanner.currentPosition<this.index ? this.index : this.scanner.currentPosition;
+		if (startPos == this.source.length)
+			return "EOF\n\n" + new String(this.source); //$NON-NLS-1$
+		if (endPos > this.source.length)
+			return "behind the EOF\n\n" + new String(this.source); //$NON-NLS-1$
+	
+		char front[] = new char[startPos];
+		System.arraycopy(this.source, 0, front, 0, startPos);
+	
+		int middleLength = (endPos - 1) - startPos + 1;
+		char middle[];
+		if (middleLength > -1) {
+			middle = new char[middleLength];
+			System.arraycopy(
+				this.source, 
+				startPos, 
+				middle, 
+				0, 
+				middleLength);
+		} else {
+			middle = CharOperation.NO_CHAR;
+		}
+		
+		char end[] = new char[this.source.length - (endPos - 1)];
+		System.arraycopy(
+			this.source, 
+			(endPos - 1) + 1, 
+			end, 
+			0, 
+			this.source.length - (endPos - 1) - 1);
+		
+		buffer.append(front);
+		if (this.scanner.currentPosition<this.index) {
+			buffer.append("\n===============================\nScanner current position here -->"); //$NON-NLS-1$
+		} else {
+			buffer.append("\n===============================\nParser index here -->"); //$NON-NLS-1$
+		}
+		buffer.append(middle);
+		if (this.scanner.currentPosition<this.index) {
+			buffer.append("<-- Parser index here\n===============================\n"); //$NON-NLS-1$
+		} else {
+			buffer.append("<-- Scanner current position here\n===============================\n"); //$NON-NLS-1$
+		}
+		buffer.append(end);
+
+		return buffer.toString();
+	}
+
+	/*
+	 * Update line end
+	 */
+	protected void updateLineEnd() {
+		while (this.index > (this.lineEnd+1)) { // be sure to be on next line (lineEnd is still on the same line)
+			if (this.linePtr < this.lastLinePtr) {
+				this.lineEnd = getLineEnd(++this.linePtr) - 1;
+			} else {
+				this.lineEnd = this.endComment;
+				return;
+			}
+		}
+	}
+	protected abstract void updateDocComment();
+
+	/**
+	 * Search the line number corresponding to a specific position.
+	 * Warning: returned position is 1-based index!
+	 * @see Scanner#getLineNumber(int) We cannot directly use this method
+	 * when linePtr field is not initialized.
+	 */
+	public final int getLineNumber(int position) {
+	
+		if (this.scanner.linePtr != -1) {
+			return this.scanner.getLineNumber(position);
+		}
+		if (this.lineEnds == null)
+			return 1;
+		int length = this.lineEnds.length;
+		if (length == 0)
+			return 1;
+		int g = 0, d = length - 1;
+		int m = 0;
+		while (g <= d) {
+			m = (g + d) /2;
+			if (position < this.lineEnds[m]) {
+				d = m-1;
+			} else if (position > this.lineEnds[m]) {
+				g = m+1;
+			} else {
+				return m + 1;
+			}
+		}
+		if (position < this.lineEnds[m]) {
+			return m+1;
+		}
+		return m+2;
+	}
+
+	/**
+	 * Search the source position corresponding to the end of a given line number.
+	 * Warning: returned position is 1-based index!
+	 * @see Scanner#getLineEnd(int) We cannot directly use this method
+	 * when linePtr field is not initialized.
+	 */
+	public final int getLineEnd(int lineNumber) {
+	
+		if (this.scanner.linePtr != -1) {
+			return this.scanner.getLineEnd(lineNumber);
+		}
+		if (this.lineEnds == null) 
+			return -1;
+		if (lineNumber > this.lineEnds.length+1) 
+			return -1;
+		if (lineNumber <= 0) 
+			return -1;
+		if (lineNumber == this.lineEnds.length + 1) 
+			return this.scanner.eofPosition;
+		return this.lineEnds[lineNumber-1]; // next line start one character behind the lineEnd of the previous line
+	}
+}
