JDK_1_5 - Merge with HEAD: v440a
diff --git a/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties b/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties
index d302c7a..b11b635 100644
--- a/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties
+++ b/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties
@@ -12,7 +12,7 @@
 
 ### compiler 
 compiler.name = Eclipse Java Compiler
-compiler.version = 0.436_Cheetah06
+compiler.version = 0.440_Cheetah06
 compiler.copyright = Copyright IBM Corp 2000, 2004. All rights reserved.
 
 ### scanning
diff --git a/buildnotes_jdt-core.html b/buildnotes_jdt-core.html
index 3d83c11..76f6cac 100644
--- a/buildnotes_jdt-core.html
+++ b/buildnotes_jdt-core.html
@@ -159,6 +159,120 @@
 [1.5] ArrayStoreException in 1.5 parser
 
 
+<a name="v_440"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.0RC2 Build - 10th June 2004 - 3.0 RELEASE CANDIDATE 2
+<br>Project org.eclipse.jdt.core v_440
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_440">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=66551">66551</a>
+Error in org.eclipse.swt project on class PrinterData
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=66573">66573</a>
+Shouldn't bind to local constructs
+
+<a name="v_439"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.0RC2 Build - 10th June 2004
+<br>Project org.eclipse.jdt.core v_439
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_439">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=66216">66216</a>
+Sort Members is broken.
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=66437">66437</a>
+Canceling search leads to broken workspace 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=65266">65266</a>
+JarPackageFragmentInfo has unnecessary field 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=66098">66098</a>
+MatchLocatorParser does not need advanced syntax diagnosis
+
+<a name="v_438"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.0RC2 Build - 9th June 2004
+<br>Project org.eclipse.jdt.core v_438
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_438">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=66026">66026</a>
+Large amount of garbage created by DefaultCommentMapper
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=64646">64646</a>
+[Navigator] Navigator popup causes Eclipse to hang. 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=65288">65288</a>
+Javadoc: tag gets mangled when javadoc closing on same line without whitespace
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=65253">65253</a>
+[Javadoc] @@tag is wrongly parsed as @tag
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=65180">65180</a>
+Spurious "Javadoc: xxx cannot be resolved or is not a field" error with inner classes
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=65174">65174</a>
+Spurious "Javadoc: Missing reference" error
+
+<a name="v_437"></a>
+<p><hr><h1>
+Eclipse Platform Build Notes&nbsp;<br>
+Java Development Tooling Core</h1>
+Eclipse SDK 3.0RC2 Build - 8th June 2004
+<br>Project org.eclipse.jdt.core v_437
+(<a href="http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.core/?only_with_tag=v_437">cvs</a>).
+<h2>
+What's new in this drop</h2>
+<ul>
+</ul>
+
+<h3>Problem Reports Fixed</h3>
+<a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=66142">66142</a>
+SearchParticipant#scheduleDocumentIndexing() fails silently if index doesn't exist 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=65795">65795</a>
+source inclusion mechanism breaks type lookups 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=66099">66099</a>
+Persisted container/variable values are leaked throughout a session
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=65250">65250</a>
+Problem selection does not choose first n errors
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=65259">65259</a>
+CodeSelect should only find one match for dup methods
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=65737">65737</a>
+Strange completion by code assist 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=65871">65871</a>
+Missing SUPER_INTERFACE_TYPES_PROPERTY in EnumDeclaration 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=53072">53072</a>
+[DOC] Search for fully qualified constructor name reports nothing 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=65116">65116</a>
+IProjectDescription.getBuildSpec copies commands 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=65234">65234</a>
+Inclusion filter not working 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=64657">64657</a>
+better documentation for IType#resolveType behavior 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=65693">65693</a>
+Package Explorer shows .class files instead of .java 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=64750">64750</a>
+NPE in Java AST Creation - editing some random file 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=65562">65562</a>
+Java AST creation failure
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=65531">65531</a>
+out of the box formatter settings need to be improved
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=65677">65677</a>
+Creating hierarchy failed. See log for details. 0 
+<br><a href="http://bugs.eclipse.org/bugs/show_bug.cgi?id=65090">65090</a>
+ASTParser with kind == K_STATEMENTS doesn't work unless source range specified
+	  	
 <a name="v_436"></a>
 <p><hr><h1>
 Eclipse Platform Build Notes&nbsp;<br>
diff --git a/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java b/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java
index 248d8a6..f293f33 100644
--- a/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java
+++ b/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java
@@ -2100,6 +2100,9 @@
 						if(method.declaringClass == scope.getJavaLangObject())
 							continue next;
 						
+						if (method.declaringClass.isInterface())
+							continue next;
+						
 						if (!superCall && method
 							.declaringClass
 							.implementsInterface(otherMethod.declaringClass, true))
diff --git a/codeassist/org/eclipse/jdt/internal/codeassist/ISelectionRequestor.java b/codeassist/org/eclipse/jdt/internal/codeassist/ISelectionRequestor.java
index 5345d75..8e86534 100644
--- a/codeassist/org/eclipse/jdt/internal/codeassist/ISelectionRequestor.java
+++ b/codeassist/org/eclipse/jdt/internal/codeassist/ISelectionRequestor.java
@@ -116,6 +116,15 @@
 	 * 
 	 *  @param isConstructor boolean
 	 * 		Answer if the method is a constructor.
+	 * 
+	 * @param isDeclaration boolean
+	 *  	Answer if the selected method is a declaration
+	 * 
+	 * @param start
+	 *  	Start of the selection
+	 * 
+	 * @param end
+	 *  	End of the selection
 	 *
 	 * NOTE - All package and type names are presented in their readable form:
 	 *    Package names are in the form "a.b.c".
@@ -124,14 +133,18 @@
 	 *    Nested type names are in the qualified form "A.M".
 	 *    The default package is represented by an empty array.
 	 */
+	// parameters 'isDeclaration', 'start' and 'end' are use to distinguish duplicate methods declarations
 	void acceptMethod(
 		char[] declaringTypePackageName,
 		char[] declaringTypeName,
 		char[] selector,
 		char[][] parameterPackageNames,
 		char[][] parameterTypeNames,
-		boolean isConstructor);
-
+		boolean isConstructor,
+		boolean isDeclaration,
+		int start,
+		int end);
+	
 	/**
 	 * Code assist notification of a package selection.
 	 * @param packageName char[]
diff --git a/codeassist/org/eclipse/jdt/internal/codeassist/SelectionEngine.java b/codeassist/org/eclipse/jdt/internal/codeassist/SelectionEngine.java
index 6eadacd..e79dcca 100644
--- a/codeassist/org/eclipse/jdt/internal/codeassist/SelectionEngine.java
+++ b/codeassist/org/eclipse/jdt/internal/codeassist/SelectionEngine.java
@@ -514,7 +514,7 @@
 									System.out.println(e.binding.toString());
 								}
 								// if null then we found a problem in the selection node
-								selectFrom(e.binding, parsedUnit);
+								selectFrom(e.binding, parsedUnit, e.isDeclaration);
 							}
 						}
 					}
@@ -540,7 +540,7 @@
 		}
 	}
 
-	private void selectFrom(Binding binding, CompilationUnitDeclaration parsedUnit) {
+	private void selectFrom(Binding binding, CompilationUnitDeclaration parsedUnit, boolean isDeclaration) {
 		if (binding instanceof ReferenceBinding) {
 			ReferenceBinding typeBinding = (ReferenceBinding) binding;
 			if (qualifiedSelection != null
@@ -609,7 +609,10 @@
 						parameterPackageNames,
 						parameterTypeNames,
 						methodBinding.isConstructor(),
-						parsedUnit);
+						parsedUnit,
+						isDeclaration,
+						actualSelectionStart,
+						actualSelectionEnd);
 				} else {
 					this.requestor.acceptMethod(
 						declaringClass.qualifiedPackageName(),
@@ -619,7 +622,10 @@
 							: methodBinding.selector,
 						parameterPackageNames,
 						parameterTypeNames,
-						methodBinding.isConstructor());
+						methodBinding.isConstructor(), 
+						isDeclaration,
+						actualSelectionStart,
+						actualSelectionEnd);
 				}
 				this.acceptedAnswer = true;
 			} else
@@ -650,11 +656,11 @@
 							this.acceptedAnswer = true;
 						} else {
 							// open on the type of the variable
-							selectFrom(((LocalVariableBinding) binding).type, parsedUnit);
+							selectFrom(((LocalVariableBinding) binding).type, parsedUnit, false);
 						}
 					} else
 						if (binding instanceof ArrayBinding) {
-							selectFrom(((ArrayBinding) binding).leafComponentType, parsedUnit);
+							selectFrom(((ArrayBinding) binding).leafComponentType, parsedUnit, false);
 							// open on the type of the array
 						} else
 							if (binding instanceof PackageBinding) {
@@ -824,7 +830,7 @@
 									System.out.println(e.binding.toString());
 								}
 								// if null then we found a problem in the selection node
-								selectFrom(e.binding, parsedUnit);
+								selectFrom(e.binding, parsedUnit, e.isDeclaration);
 							}
 						}
 					}
@@ -870,7 +876,7 @@
 	private void selectDeclaration(TypeDeclaration typeDeclaration, char[] assistIdentifier){
 	
 		if (typeDeclaration.name == assistIdentifier){
-			throw new SelectionNodeFound(typeDeclaration.binding);
+			throw new SelectionNodeFound(typeDeclaration.binding, true);
 		}
 		TypeDeclaration[] memberTypes = typeDeclaration.memberTypes;
 		for (int i = 0, length = memberTypes == null ? 0 : memberTypes.length; i < length; i++){
@@ -879,7 +885,7 @@
 		FieldDeclaration[] fields = typeDeclaration.fields;
 		for (int i = 0, length = fields == null ? 0 : fields.length; i < length; i++){
 			if (fields[i].name == assistIdentifier){
-				throw new SelectionNodeFound(fields[i].binding);
+				throw new SelectionNodeFound(fields[i].binding, true);
 			}
 		}
 		AbstractMethodDeclaration[] methods = typeDeclaration.methods;
@@ -887,10 +893,10 @@
 			AbstractMethodDeclaration method = methods[i];
 			if (method.selector == assistIdentifier){
 				if(method.binding != null) {
-					throw new SelectionNodeFound(method.binding);
+					throw new SelectionNodeFound(method.binding, true);
 				} else {
 					if(method.scope != null) {
-						throw new SelectionNodeFound(new MethodBinding(method.modifiers, method.selector, null, null, null, method.scope.referenceType().binding));
+						throw new SelectionNodeFound(new MethodBinding(method.modifiers, method.selector, null, null, null, method.scope.referenceType().binding), true);
 					}
 				}
 			}
diff --git a/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionScanner.java b/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionScanner.java
index c4f0fa5..03c9335 100644
--- a/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionScanner.java
+++ b/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionScanner.java
@@ -119,13 +119,7 @@
 			//need the unicode buffer
 			if (this.withoutUnicodePtr == 0) {
 				//buffer all the entries that have been left aside....
-				this.withoutUnicodePtr = this.currentPosition - unicodeSize - this.startPosition;
-				System.arraycopy(
-					this.source, 
-					this.startPosition, 
-					this.withoutUnicodeBuffer, 
-					1, 
-					this.withoutUnicodePtr); 
+				unicodeInitializeBuffer(this.currentPosition - unicodeSize - this.startPosition);
 			}
 			if (temp < this.cursorLocation && this.cursorLocation < this.currentPosition-1){
 				throw new InvalidCursorLocation(InvalidCursorLocation.NO_COMPLETION_INSIDE_UNICODE);
@@ -134,7 +128,7 @@
 			// Note: this does not handle cases where the cursor is in the middle of a unicode
 			if ((this.completionIdentifier != null)
 				|| (this.startPosition <= this.cursorLocation+1 && this.cursorLocation >= this.currentPosition-1)){
-				this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+			    unicodeStoreAt(++this.withoutUnicodePtr);
 			}
 			return true;
 		} //-------------end unicode traitement--------------
@@ -148,8 +142,8 @@
 				// store the current unicode, only if we did not pass the cursor location
 				// Note: this does not handle cases where the cursor is in the middle of a unicode
 				if ((this.completionIdentifier != null)
-					|| (this.startPosition <= this.cursorLocation+1 && this.cursorLocation >= this.currentPosition-1)){
-					this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+						|| (this.startPosition <= this.cursorLocation+1 && this.cursorLocation >= this.currentPosition-1)){
+				    unicodeStoreAt(++this.withoutUnicodePtr);
 				}
 			}
 			return true;
@@ -382,7 +376,7 @@
 							getNextUnicodeChar();
 						} else {
 							if (this.withoutUnicodePtr != 0) {
-								this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+							    this.unicodeStoreAt(++this.withoutUnicodePtr);
 							}
 						}
 					}
@@ -409,7 +403,7 @@
 							getNextUnicodeChar();
 						} else {
 							if (this.withoutUnicodePtr != 0) {
-								this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+							    this.unicodeStoreAt(++this.withoutUnicodePtr);
 							}
 						}
 
@@ -437,16 +431,11 @@
 								escapeSize = this.currentPosition - escapeSize;
 								if (this.withoutUnicodePtr == 0) {
 									//buffer all the entries that have been left aside....
-									this.withoutUnicodePtr = this.currentPosition - escapeSize - 1 - this.startPosition;
-									System.arraycopy(
-										this.source, 
-										this.startPosition, 
-										this.withoutUnicodeBuffer, 
-										1, 
-										this.withoutUnicodePtr); 
-									this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+
+									unicodeInitializeBuffer(this.currentPosition - escapeSize - 1 - this.startPosition);
+									this.unicodeStoreAt(++this.withoutUnicodePtr);
 								} else { //overwrite the / in the buffer
-									this.withoutUnicodeBuffer[this.withoutUnicodePtr] = this.currentCharacter;
+								    this.unicodeStoreAt(this.withoutUnicodePtr);
 									if (backSlashAsUnicodeInString) { //there are TWO \ in the stream where only one is correct
 										this.withoutUnicodePtr--;
 									}
@@ -459,7 +448,7 @@
 								getNextUnicodeChar();
 							} else {
 								if (this.withoutUnicodePtr != 0) {
-									this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+								    this.unicodeStoreAt(++this.withoutUnicodePtr);
 								}
 							}
 
@@ -581,7 +570,7 @@
 								getNextUnicodeChar();
 							} else {
 								if (this.withoutUnicodePtr != 0) {
-									this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+								    this.unicodeStoreAt(++this.withoutUnicodePtr);
 								}
 							}
 
diff --git a/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionNodeFound.java b/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionNodeFound.java
index e2fa1de..7feb67e 100644
--- a/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionNodeFound.java
+++ b/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionNodeFound.java
@@ -14,10 +14,15 @@
 
 public class SelectionNodeFound extends RuntimeException {
 	public Binding binding;
+	public boolean isDeclaration;
 public SelectionNodeFound() {
 	this(null); // we found a problem in the selection node
 }
 public SelectionNodeFound(Binding binding) {
+	this(binding, false);
+}
+public SelectionNodeFound(Binding binding, boolean isDeclaration) {
 	this.binding = binding;
+	this.isDeclaration = isDeclaration;
 }
 }
diff --git a/compiler/org/eclipse/jdt/internal/compiler/CompilationResult.java b/compiler/org/eclipse/jdt/internal/compiler/CompilationResult.java
index d14fd18..d6b7475 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/CompilationResult.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/CompilationResult.java
@@ -86,12 +86,12 @@
 
 	private int computePriority(IProblem problem){
 	
-		final int P_STATIC = 1000;
-		final int P_OUTSIDE_METHOD = 4000;
-		final int P_FIRST_ERROR = 2000;
-		final int P_ERROR = 10000;
+		final int P_STATIC = 10000;
+		final int P_OUTSIDE_METHOD = 40000;
+		final int P_FIRST_ERROR = 20000;
+		final int P_ERROR = 100000;
 		
-		int priority = 1000 - problem.getSourceLineNumber(); // early problems first
+		int priority = 10000 - problem.getSourceLineNumber(); // early problems first
 		if (priority < 0) priority = 0;
 		if (problem.isError()){
 			priority += P_ERROR;
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java b/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java
index 7845af0..1173664 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java
@@ -356,8 +356,8 @@
 		try {
 			bindArguments(); 
 			bindThrownExceptions();
-			resolveStatements();
 			resolveJavadoc();
+			resolveStatements();
 		} catch (AbortMethod e) {	// ========= abort on fatal error =============
 			this.ignoreFurtherInvestigation = true;
 		} 
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java b/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java
index e43cb66..f683964 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/Javadoc.java
@@ -112,6 +112,7 @@
 			if (this.references[i] instanceof JavadocFieldReference) {
 				JavadocFieldReference fieldRef = (JavadocFieldReference) this.references[i];
 				if (fieldRef.receiverType != null && fieldRef.binding == null) { // binding was reset in case of valid method reference
+					// TODO (frederic) post 3.0 - avoid new instanciation of Compiler AST node
 					JavadocMessageSend msgSend = new JavadocMessageSend(fieldRef.token, fieldRef.nameSourcePosition);
 					msgSend.receiver = fieldRef.receiver;
 					msgSend.receiverType = fieldRef.receiverType;
@@ -146,6 +147,7 @@
 			if (this.references[i] instanceof JavadocFieldReference) {
 				JavadocFieldReference fieldRef = (JavadocFieldReference) this.references[i];
 				if (fieldRef.receiverType != null && fieldRef.binding == null) { // binding was reset in case of valid method reference
+					// TODO (frederic) post 3.0 - avoid new instanciation of Compiler AST node
 					JavadocMessageSend msgSend = new JavadocMessageSend(fieldRef.token, fieldRef.nameSourcePosition);
 					msgSend.receiver = fieldRef.receiver;
 					msgSend.receiverType = fieldRef.receiverType;
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocFieldReference.java b/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocFieldReference.java
index db8d3ad..04f1016 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocFieldReference.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocFieldReference.java
@@ -39,28 +39,44 @@
 			return null;
 		}
 
-		this.binding = scope.getField(this.receiverType, this.token, this);
-		if (!this.binding.isValidBinding()) {
+		Binding fieldBinding = (this.receiver != null && this.receiver.isThis())
+			? scope.classScope().getBinding(this.token, this.bits & RestrictiveFlagMASK, this, true /*resolve*/)
+			: scope.getField(this.receiverType, this.token, this);
+		if (!fieldBinding.isValidBinding()) {
+			// implicit lookup may discover issues due to static/constructor contexts. javadoc must be resilient
+			switch (fieldBinding.problemId()) {
+				case ProblemReasons.NonStaticReferenceInConstructorInvocation:
+				case ProblemReasons.NonStaticReferenceInStaticContext:
+				case ProblemReasons.InheritedNameHidesEnclosingName : 
+					FieldBinding closestMatch = ((ProblemFieldBinding)fieldBinding).closestMatch;
+					if (closestMatch != null) {
+						fieldBinding = closestMatch; // ignore problem if can reach target field through it
+					}
+			}
+		}			
+		if (!fieldBinding.isValidBinding() || !(fieldBinding instanceof FieldBinding)) {
 			if (this.receiverType instanceof ReferenceBinding) {
 				ReferenceBinding refBinding = (ReferenceBinding) this.receiverType;
 				MethodBinding[] bindings = refBinding.getMethods(this.token);
 				if (bindings == null) {
-					scope.problemReporter().javadocInvalidField(this, this.receiverType, scope.getDeclarationModifiers());
-					return null;
-				} 
-				switch (bindings.length) {
-					case 0:
-						scope.problemReporter().javadocInvalidField(this, this.receiverType, scope.getDeclarationModifiers());
-						return null;
-					case 1:
-						this.binding = null;
-						return null;
-					default:
-						scope.problemReporter().javadocAmbiguousMethodReference(this, scope.getDeclarationModifiers());
-						return null;
+					scope.problemReporter().javadocInvalidField(this.sourceStart, this.sourceEnd, fieldBinding, this.receiverType, scope.getDeclarationModifiers());
+				} else {
+					switch (bindings.length) {
+						case 0:
+							scope.problemReporter().javadocInvalidField(this.sourceStart, this.sourceEnd, fieldBinding, this.receiverType, scope.getDeclarationModifiers());
+							break;
+						case 1:
+							this.binding = null;
+							break;
+						default:
+							scope.problemReporter().javadocAmbiguousMethodReference(this.sourceStart, this.sourceEnd, fieldBinding, scope.getDeclarationModifiers());
+							break;
+					}
 				}
 			}
+			return null;
 		}
+		this.binding = (FieldBinding) fieldBinding;
 
 		if (isFieldUseDeprecated(this.binding, scope, (this.bits & IsStrictlyAssignedMASK) != 0)) {
 			scope.problemReporter().javadocDeprecatedField(this.binding, this, scope.getDeclarationModifiers());
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocMessageSend.java b/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocMessageSend.java
index 51a6202..1f0fa66 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocMessageSend.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/JavadocMessageSend.java
@@ -80,7 +80,21 @@
 			scope.problemReporter().javadocErrorNoMethodFor(this, this.receiverType, argumentTypes, scope.getDeclarationModifiers());
 			return null;
 		}
-		this.binding = scope.getMethod(this.receiverType, this.selector, argumentTypes, this); 
+		this.binding = (this.receiver != null && this.receiver.isThis())
+			? scope.getImplicitMethod(this.selector, argumentTypes, this)
+			: scope.getMethod(this.receiverType, this.selector, argumentTypes, this);
+		if (!this.binding.isValidBinding()) {
+			// implicit lookup may discover issues due to static/constructor contexts. javadoc must be resilient
+			switch (this.binding.problemId()) {
+				case ProblemReasons.NonStaticReferenceInConstructorInvocation:
+				case ProblemReasons.NonStaticReferenceInStaticContext:
+				case ProblemReasons.InheritedNameHidesEnclosingName : 
+					MethodBinding closestMatch = ((ProblemMethodBinding)this.binding).closestMatch;
+					if (closestMatch != null) {
+						this.binding = closestMatch; // ignore problem if can reach target method through it
+					}
+			}
+		}
 		if (!this.binding.isValidBinding()) {
 			if (this.binding.declaringClass == null) {
 				if (this.receiverType instanceof ReferenceBinding) {
diff --git a/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java b/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
index 947d5b7..f796d0d 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java
@@ -293,18 +293,20 @@
 			}
 		}
 		scope.problemReporter().invalidMethod(this, binding);
-		// record the closest match, for clients who may still need hint about possible method match
 		MethodBinding closestMatch = ((ProblemMethodBinding)binding).closestMatch;
-		if (closestMatch != null) this.binding = closestMatch;
-		switch (binding.problemId()) {
+		switch (this.binding.problemId()) {
+			case ProblemReasons.Ambiguous :
 			case ProblemReasons.NotVisible :
 			case ProblemReasons.NonStaticReferenceInConstructorInvocation :
 			case ProblemReasons.NonStaticReferenceInStaticContext :
 			case ProblemReasons.ReceiverTypeNotVisible :
 			case ProblemReasons.ParameterBoundMismatch :
-				if (binding != null) this.resolvedType = binding.returnType;
+				// only steal returnType in cases listed above
+				if (closestMatch != null) this.resolvedType = closestMatch.returnType;
 			default :
 		}
+		// record the closest match, for clients who may still need hint about possible method match
+		if (closestMatch != null) this.binding = closestMatch;
 		return this.resolvedType;
 	}
 	if (!binding.isStatic()) {
diff --git a/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java b/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java
index b17595f..7aec944 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java
@@ -726,173 +726,6 @@
 		return null;
 	}
 
-	/* API
-	 *	
-	 *	Answer the method binding that corresponds to selector, argumentTypes.
-	 *	Start the lookup at the enclosing type of the receiver.
-	 *	InvocationSite implements 
-	 *		isSuperAccess(); this is used to determine if the discovered method is visible.
-	 *		setDepth(int); this is used to record the depth of the discovered method
-	 *			relative to the enclosing type of the receiver. (If the method is defined
-	 *			in the enclosing type of the receiver, the depth is 0; in the next enclosing
-	 *			type, the depth is 1; and so on
-	 * 
-	 *	If no visible method is discovered, an error binding is answered.
-	 */
-	public MethodBinding getImplicitMethod(char[] selector, TypeBinding[] argumentTypes, InvocationSite invocationSite) {
-
-		boolean insideStaticContext = false;
-		boolean insideConstructorCall = false;
-		MethodBinding foundMethod = null;
-		MethodBinding foundFuzzyProblem = null;
-		// the weird method lookup case (matches method name in scope, then arg types, then visibility)
-		MethodBinding foundInsideProblem = null;
-		// inside Constructor call or inside static context
-		Scope scope = this;
-		int depth = 0;
-		done : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
-			switch (scope.kind) {
-				case METHOD_SCOPE :
-					MethodScope methodScope = (MethodScope) scope;
-					insideStaticContext |= methodScope.isStatic;
-					insideConstructorCall |= methodScope.isConstructorCall;
-					break;
-				case CLASS_SCOPE :
-					ClassScope classScope = (ClassScope) scope;
-					SourceTypeBinding receiverType = classScope.referenceContext.binding;
-					boolean isExactMatch = true;
-					// retrieve an exact visible match (if possible)
-					MethodBinding methodBinding =
-						(foundMethod == null)
-							? classScope.findExactMethod(receiverType, selector, argumentTypes, invocationSite)
-							: classScope.findExactMethod( receiverType, foundMethod.selector, foundMethod.parameters, invocationSite);
-					//		? findExactMethod(receiverType, selector, argumentTypes, invocationSite)
-					//		: findExactMethod(receiverType, foundMethod.selector, foundMethod.parameters, invocationSite);
-					if (methodBinding == null) {
-						// answers closest approximation, may not check argumentTypes or visibility
-						isExactMatch = false;
-						methodBinding = classScope.findMethod(receiverType, selector, argumentTypes, invocationSite);
-						// methodBinding = findMethod(receiverType, selector, argumentTypes, invocationSite);
-					}
-					if (methodBinding != null) { // skip it if we did not find anything
-						if (methodBinding.problemId() == Ambiguous) {
-							if (foundMethod == null || foundMethod.problemId() == NotVisible) {
-								// supercedes any potential InheritedNameHidesEnclosingName problem
-								return methodBinding;
-							}
-							// make the user qualify the method, likely wants the first inherited method (javac generates an ambiguous error instead)
-							return new ProblemMethodBinding(
-								selector,
-								argumentTypes,
-								InheritedNameHidesEnclosingName);
-						}
-						MethodBinding fuzzyProblem = null;
-						MethodBinding insideProblem = null;
-						if (methodBinding.isValidBinding()) {
-							if (!isExactMatch) {
-								MethodBinding compatibleMethod = computeCompatibleMethod(methodBinding, argumentTypes, invocationSite);
-								if (compatibleMethod == null) {
-									if (foundMethod == null || foundMethod.problemId() == NotVisible)
-										// inherited mismatch is reported directly, not looking at enclosing matches
-										return new ProblemMethodBinding(methodBinding, selector, argumentTypes, NotFound);
-									// make the user qualify the method, likely wants the first inherited method (javac generates an ambiguous error instead)
-									fuzzyProblem = new ProblemMethodBinding(selector, methodBinding.parameters, InheritedNameHidesEnclosingName);
-								} else if (!compatibleMethod.isValidBinding()) {
-									fuzzyProblem = compatibleMethod;
-								} else {
-									methodBinding = compatibleMethod;
-									if (!methodBinding.canBeSeenBy(receiverType, invocationSite, classScope)) {
-										// using <classScope> instead of <this> for visibility check does grant all access to innerclass
-										fuzzyProblem = new ProblemMethodBinding(methodBinding, selector, methodBinding.parameters, NotVisible);
-									}
-								}
-							}
-							if (fuzzyProblem == null && !methodBinding.isStatic()) {
-								if (insideConstructorCall) {
-									insideProblem =
-										new ProblemMethodBinding(
-											methodBinding.selector,
-											methodBinding.parameters,
-											NonStaticReferenceInConstructorInvocation);
-								} else if (insideStaticContext) {
-									insideProblem =
-										new ProblemMethodBinding(
-											methodBinding.selector,
-											methodBinding.parameters,
-											NonStaticReferenceInStaticContext);
-								}
-							}
-							
-							if (receiverType == methodBinding.declaringClass
-								|| (receiverType.getMethods(selector)) != NoMethods
-								|| ((fuzzyProblem == null || fuzzyProblem.problemId() != NotVisible) && environment().options.complianceLevel >= ClassFileConstants.JDK1_4)){
-								// found a valid method in the 'immediate' scope (ie. not inherited)
-								// OR the receiverType implemented a method with the correct name
-								// OR in 1.4 mode (inherited visible shadows enclosing)
-								if (foundMethod == null) {
-									if (depth > 0){
-										invocationSite.setDepth(depth);
-										invocationSite.setActualReceiverType(receiverType);
-									}
-									// return the methodBinding if it is not declared in a superclass of the scope's binding (that is, inherited)
-									if (fuzzyProblem != null)
-										return fuzzyProblem;
-									if (insideProblem != null)
-										return insideProblem;
-									return methodBinding;
-								}
-								// if a method was found, complain when another is found in an 'immediate' enclosing type (that is, not inherited)
-								// NOTE: Unlike fields, a non visible method hides a visible method
-								if (foundMethod.declaringClass != methodBinding.declaringClass)
-									// ie. have we found the same method - do not trust field identity yet
-									return new ProblemMethodBinding(
-										methodBinding.selector,
-										methodBinding.parameters,
-										InheritedNameHidesEnclosingName);
-							}
-						}
-
-						if (foundMethod == null
-							|| (foundMethod.problemId() == NotVisible
-								&& methodBinding.problemId() != NotVisible)) {
-							// only remember the methodBinding if its the first one found or the previous one was not visible & methodBinding is...
-							// remember that private methods are visible if defined directly by an enclosing class
-							if (depth > 0){
-								invocationSite.setDepth(depth);
-								invocationSite.setActualReceiverType(receiverType);
-							}
-							foundFuzzyProblem = fuzzyProblem;
-							foundInsideProblem = insideProblem;
-							if (fuzzyProblem == null)
-								foundMethod = methodBinding; // only keep it if no error was found
-						}
-					}
-					depth++;
-					insideStaticContext |= receiverType.isStatic();
-					// 1EX5I8Z - accessing outer fields within a constructor call is permitted
-					// in order to do so, we change the flag as we exit from the type, not the method
-					// itself, because the class scope is used to retrieve the fields.
-					MethodScope enclosingMethodScope = scope.methodScope();
-					insideConstructorCall =
-						enclosingMethodScope == null ? false : enclosingMethodScope.isConstructorCall;
-					break;
-				case COMPILATION_UNIT_SCOPE :
-					break done;
-			}
-			scope = scope.parent;
-		}
-
-		if (foundFuzzyProblem != null)
-			return foundFuzzyProblem;
-		if (foundInsideProblem != null)
-			return foundInsideProblem;
-		if (foundMethod != null)
-			return foundMethod;
-		return new ProblemMethodBinding(selector, argumentTypes, NotFound);
-	}
-	
-
-	
 	/* Answer true if the variable name already exists within the receiver's scope.
 	 */
 	public final boolean isDuplicateLocalVariable(char[] name) {
diff --git a/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodScope.java b/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodScope.java
index bcac64d..5f0b837 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodScope.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/lookup/MethodScope.java
@@ -355,6 +355,7 @@
 
 		if (invocationSite instanceof SingleNameReference)
 			return new ProblemFieldBinding(
+				field, // closest match
 				field.declaringClass,
 				fieldName,
 				NonStaticReferenceInConstructorInvocation);
@@ -364,6 +365,7 @@
 			if (name.binding == null)
 				// only true when the field is the fieldbinding at the beginning of name's tokens
 				return new ProblemFieldBinding(
+					field, // closest match
 					field.declaringClass,
 					fieldName,
 					NonStaticReferenceInConstructorInvocation);
diff --git a/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemFieldBinding.java b/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemFieldBinding.java
index f4c518e..ec3012d 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemFieldBinding.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/lookup/ProblemFieldBinding.java
@@ -14,12 +14,18 @@
 
 public class ProblemFieldBinding extends FieldBinding {
 	private int problemId;
+	public FieldBinding closestMatch;
+		
 // NOTE: must only answer the subset of the name related to the problem
 
 public ProblemFieldBinding(ReferenceBinding declaringClass, char[][] compoundName, int problemId) {
-	this(declaringClass, CharOperation.concatWith(compoundName, '.'), problemId);
+	this(null, declaringClass, CharOperation.concatWith(compoundName, '.'), problemId);
 }
 public ProblemFieldBinding(ReferenceBinding declaringClass, char[] name, int problemId) {
+	this(null, declaringClass, name, problemId);
+}
+public ProblemFieldBinding(FieldBinding closestMatch, ReferenceBinding declaringClass, char[] name, int problemId) {
+	this.closestMatch = closestMatch;
 	this.declaringClass = declaringClass;
 	this.name = name;
 	this.problemId = problemId;
diff --git a/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java b/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
index 7df082f..e09e827 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java
@@ -49,6 +49,16 @@
 			return MoreGeneric;
 		return NotRelated;
 	}
+	
+	public final ClassScope classScope() {
+		Scope scope = this;
+		do {
+			if (scope instanceof ClassScope)
+				return (ClassScope) scope;
+			scope = scope.parent;
+		} while (scope != null);
+		return null;
+	}	
 
 	/* Answer an int describing the relationship between the given type and unchecked exceptions.
 	*
@@ -472,7 +482,7 @@
 		if (field != null) {
 			if (field.canBeSeenBy(currentType, invocationSite, this))
 				return field;
-			return new ProblemFieldBinding(field.declaringClass, fieldName, NotVisible);
+			return new ProblemFieldBinding(field /* closest match*/, field.declaringClass, fieldName, NotVisible);
 		}
 		// collect all superinterfaces of receiverType until the field is found in a supertype
 		ReferenceBinding[][] interfacesToVisit = null;
@@ -504,7 +514,7 @@
 					if (visibleField == null)
 						visibleField = field;
 					else
-						return new ProblemFieldBinding(visibleField.declaringClass, fieldName, Ambiguous);
+						return new ProblemFieldBinding(visibleField /* closest match*/, visibleField.declaringClass, fieldName, Ambiguous);
 				} else {
 					notVisible = true;
 				}
@@ -525,7 +535,7 @@
 							if (visibleField == null) {
 								visibleField = field;
 							} else {
-								ambiguous = new ProblemFieldBinding(visibleField.declaringClass, fieldName, Ambiguous);
+								ambiguous = new ProblemFieldBinding(visibleField /* closest match*/, visibleField.declaringClass, fieldName, Ambiguous);
 								break done;
 							}
 						} else {
@@ -1137,6 +1147,7 @@
 							if (variableBinding != null) {
 								if (foundField != null && foundField.isValidBinding())
 									return new ProblemFieldBinding(
+										foundField, // closest match
 										foundField.declaringClass,
 										name,
 										InheritedNameHidesEnclosingName);
@@ -1157,12 +1168,12 @@
 									if (foundField == null || foundField.problemId() == NotVisible)
 										// supercedes any potential InheritedNameHidesEnclosingName problem
 										return fieldBinding;
-									else
-										// make the user qualify the field, likely wants the first inherited field (javac generates an ambiguous error instead)
-										return new ProblemFieldBinding(
-											fieldBinding.declaringClass,
-											name,
-											InheritedNameHidesEnclosingName);
+									// make the user qualify the field, likely wants the first inherited field (javac generates an ambiguous error instead)
+									return new ProblemFieldBinding(
+										foundField, // closest match
+										foundField.declaringClass,
+										name,
+										InheritedNameHidesEnclosingName);
 								}
 	
 								ProblemFieldBinding insideProblem = null;
@@ -1171,12 +1182,14 @@
 										if (insideConstructorCall) {
 											insideProblem =
 												new ProblemFieldBinding(
+													fieldBinding, // closest match
 													fieldBinding.declaringClass,
 													name,
 													NonStaticReferenceInConstructorInvocation);
 										} else if (insideStaticContext) {
 											insideProblem =
 												new ProblemFieldBinding(
+													fieldBinding, // closest match
 													fieldBinding.declaringClass,
 													name,
 													NonStaticReferenceInStaticContext);
@@ -1199,7 +1212,8 @@
 											if (foundField.declaringClass != fieldBinding.declaringClass)
 												// ie. have we found the same field - do not trust field identity yet
 												return new ProblemFieldBinding(
-													fieldBinding.declaringClass,
+													foundField, // closest match
+													foundField.declaringClass,
 													name,
 													InheritedNameHidesEnclosingName);
 									}
@@ -1383,6 +1397,175 @@
 		}			
 	}
 
+	/* API
+	 *	
+	 *	Answer the method binding that corresponds to selector, argumentTypes.
+	 *	Start the lookup at the enclosing type of the receiver.
+	 *	InvocationSite implements 
+	 *		isSuperAccess(); this is used to determine if the discovered method is visible.
+	 *		setDepth(int); this is used to record the depth of the discovered method
+	 *			relative to the enclosing type of the receiver. (If the method is defined
+	 *			in the enclosing type of the receiver, the depth is 0; in the next enclosing
+	 *			type, the depth is 1; and so on
+	 * 
+	 *	If no visible method is discovered, an error binding is answered.
+	 */
+	public MethodBinding getImplicitMethod(char[] selector, TypeBinding[] argumentTypes, InvocationSite invocationSite) {
+
+		boolean insideStaticContext = false;
+		boolean insideConstructorCall = false;
+		MethodBinding foundMethod = null;
+		MethodBinding foundFuzzyProblem = null;
+		// the weird method lookup case (matches method name in scope, then arg types, then visibility)
+		MethodBinding foundInsideProblem = null;
+		// inside Constructor call or inside static context
+		Scope scope = this;
+		int depth = 0;
+		done : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
+			switch (scope.kind) {
+				case METHOD_SCOPE :
+					MethodScope methodScope = (MethodScope) scope;
+					insideStaticContext |= methodScope.isStatic;
+					insideConstructorCall |= methodScope.isConstructorCall;
+					break;
+				case CLASS_SCOPE :
+					ClassScope classScope = (ClassScope) scope;
+					SourceTypeBinding receiverType = classScope.referenceContext.binding;
+					boolean isExactMatch = true;
+					// retrieve an exact visible match (if possible)
+					MethodBinding methodBinding =
+						(foundMethod == null)
+							? classScope.findExactMethod(receiverType, selector, argumentTypes, invocationSite)
+							: classScope.findExactMethod( receiverType, foundMethod.selector, foundMethod.parameters, invocationSite);
+					//		? findExactMethod(receiverType, selector, argumentTypes, invocationSite)
+					//		: findExactMethod(receiverType, foundMethod.selector, foundMethod.parameters, invocationSite);
+					if (methodBinding == null) {
+						// answers closest approximation, may not check argumentTypes or visibility
+						isExactMatch = false;
+						methodBinding = classScope.findMethod(receiverType, selector, argumentTypes, invocationSite);
+						// methodBinding = findMethod(receiverType, selector, argumentTypes, invocationSite);
+					}
+					if (methodBinding != null) { // skip it if we did not find anything
+						if (methodBinding.problemId() == Ambiguous) {
+							if (foundMethod == null || foundMethod.problemId() == NotVisible) {
+								// supercedes any potential InheritedNameHidesEnclosingName problem
+								return methodBinding;
+							}
+							// make the user qualify the method, likely wants the first inherited method (javac generates an ambiguous error instead)
+							return new ProblemMethodBinding(
+								methodBinding, // closest match
+								selector,
+								argumentTypes,
+								InheritedNameHidesEnclosingName);
+						}
+						MethodBinding fuzzyProblem = null;
+						MethodBinding insideProblem = null;
+						if (methodBinding.isValidBinding()) {
+							if (!isExactMatch) {
+								MethodBinding compatibleMethod = computeCompatibleMethod(methodBinding, argumentTypes, invocationSite);
+								if (compatibleMethod == null) {
+									if (foundMethod == null || foundMethod.problemId() == NotVisible)
+										// inherited mismatch is reported directly, not looking at enclosing matches
+										return new ProblemMethodBinding(methodBinding, selector, argumentTypes, NotFound);
+									// make the user qualify the method, likely wants the first inherited method (javac generates an ambiguous error instead)
+									fuzzyProblem = new ProblemMethodBinding(methodBinding, selector, methodBinding.parameters, InheritedNameHidesEnclosingName);
+								} else if (!compatibleMethod.isValidBinding()) {
+									fuzzyProblem = compatibleMethod;
+								} else {
+									methodBinding = compatibleMethod;
+									if (!methodBinding.canBeSeenBy(receiverType, invocationSite, classScope)) {
+										// using <classScope> instead of <this> for visibility check does grant all access to innerclass
+										fuzzyProblem = new ProblemMethodBinding(methodBinding, selector, methodBinding.parameters, NotVisible);
+									}
+								}
+							}
+							if (fuzzyProblem == null && !methodBinding.isStatic()) {
+								if (insideConstructorCall) {
+									insideProblem =
+										new ProblemMethodBinding(
+											methodBinding, // closest match
+											methodBinding.selector,
+											methodBinding.parameters,
+											NonStaticReferenceInConstructorInvocation);
+								} else if (insideStaticContext) {
+									insideProblem =
+										new ProblemMethodBinding(
+											methodBinding, // closest match
+											methodBinding.selector,
+											methodBinding.parameters,
+											NonStaticReferenceInStaticContext);
+								}
+							}
+							
+							if (receiverType == methodBinding.declaringClass
+								|| (receiverType.getMethods(selector)) != NoMethods
+								|| ((fuzzyProblem == null || fuzzyProblem.problemId() != NotVisible) && environment().options.complianceLevel >= ClassFileConstants.JDK1_4)){
+								// found a valid method in the 'immediate' scope (ie. not inherited)
+								// OR the receiverType implemented a method with the correct name
+								// OR in 1.4 mode (inherited visible shadows enclosing)
+								if (foundMethod == null) {
+									if (depth > 0){
+										invocationSite.setDepth(depth);
+										invocationSite.setActualReceiverType(receiverType);
+									}
+									// return the methodBinding if it is not declared in a superclass of the scope's binding (that is, inherited)
+									if (fuzzyProblem != null)
+										return fuzzyProblem;
+									if (insideProblem != null)
+										return insideProblem;
+									return methodBinding;
+								}
+								// if a method was found, complain when another is found in an 'immediate' enclosing type (that is, not inherited)
+								// NOTE: Unlike fields, a non visible method hides a visible method
+								if (foundMethod.declaringClass != methodBinding.declaringClass)
+									// ie. have we found the same method - do not trust field identity yet
+									return new ProblemMethodBinding(
+										methodBinding, // closest match
+										methodBinding.selector,
+										methodBinding.parameters,
+										InheritedNameHidesEnclosingName);
+							}
+						}
+
+						if (foundMethod == null
+							|| (foundMethod.problemId() == NotVisible
+								&& methodBinding.problemId() != NotVisible)) {
+							// only remember the methodBinding if its the first one found or the previous one was not visible & methodBinding is...
+							// remember that private methods are visible if defined directly by an enclosing class
+							if (depth > 0){
+								invocationSite.setDepth(depth);
+								invocationSite.setActualReceiverType(receiverType);
+							}
+							foundFuzzyProblem = fuzzyProblem;
+							foundInsideProblem = insideProblem;
+							if (fuzzyProblem == null)
+								foundMethod = methodBinding; // only keep it if no error was found
+						}
+					}
+					depth++;
+					insideStaticContext |= receiverType.isStatic();
+					// 1EX5I8Z - accessing outer fields within a constructor call is permitted
+					// in order to do so, we change the flag as we exit from the type, not the method
+					// itself, because the class scope is used to retrieve the fields.
+					MethodScope enclosingMethodScope = scope.methodScope();
+					insideConstructorCall =
+						enclosingMethodScope == null ? false : enclosingMethodScope.isConstructorCall;
+					break;
+				case COMPILATION_UNIT_SCOPE :
+					break done;
+			}
+			scope = scope.parent;
+		}
+
+		if (foundFuzzyProblem != null)
+			return foundFuzzyProblem;
+		if (foundInsideProblem != null)
+			return foundInsideProblem;
+		if (foundMethod != null)
+			return foundMethod;
+		return new ProblemMethodBinding(selector, argumentTypes, NotFound);
+	}
+
 	public final ReferenceBinding getJavaIoSerializable() {
 		compilationUnitScope().recordQualifiedReference(JAVA_IO_SERIALIZABLE);
 		ReferenceBinding type = environment().getType(JAVA_IO_SERIALIZABLE);
diff --git a/compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java b/compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java
index bba4d35..e206e5b 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/parser/AbstractCommentParser.java
@@ -51,6 +51,7 @@
 	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;
@@ -62,6 +63,8 @@
 	
 	// Private fields
 	private int currentTokenType = -1;
+	
+	// Line pointers
 	private int linePtr, lastLinePtr;
 	
 	// Identifier stack
@@ -118,7 +121,7 @@
 			this.deprecated = false;
 			this.linePtr = getLineNumber(javadocStart);
 			this.lastLinePtr = getLineNumber(javadocEnd);
-			this.lineEnd = (this.linePtr == this.lastLinePtr) ? this.endComment : javadocStart;
+			this.lineEnd = (this.linePtr == this.lastLinePtr) ? this.endComment : getLineEnd(this.linePtr);
 			this.textStart = -1;
 			char previousChar = 0;
 			int invalidTagLineEnd = -1;
@@ -132,7 +135,6 @@
 				// Calculate line end (cannot use this.scanner.linePtr as scanner does not parse line ends again)
 				if (this.index > (this.lineEnd+1)) {
 					updateLineEnd();
-					this.lineStarted = false;
 				}
 				
 				// Read next char only if token was consumed
@@ -161,7 +163,7 @@
 					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 == '{') && Character.isJavaIdentifierStart(peekChar())) {
+						if ((!this.lineStarted || previousChar == '{')) {
 							this.lineStarted = true;
 							if (this.inlineTagStarted) {
 								this.inlineTagStarted = false;
@@ -202,8 +204,7 @@
 									tagNameToken: while (tk != TerminalTokens.TokenNameEOF) {
 										this.tagSourceEnd = this.scanner.getCurrentTokenEndPosition();
 										token = tk;
-										// !, ", #, %, &, ', -, :, <, >
-										if (Character.isWhitespace(pc)) break;
+										// !, ", #, %, &, ', -, :, <, >, * chars and spaces are not allowed in tag names
 										switch (pc) {
 											case '}':
 											case '!':
@@ -213,9 +214,12 @@
 											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();
@@ -577,7 +581,7 @@
 			}
 		}
 
-		// Something Invalid input: reset ast stacks pointers
+		// Something wrong happened => Invalid input
 		throw new InvalidInputException();
 	}
 
@@ -600,6 +604,11 @@
 								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;
 									}
@@ -622,6 +631,11 @@
 				}
 			}
 		}
+		// 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;
 	}
@@ -667,11 +681,9 @@
 		end = start > end ? getEndPosition() : end;
 		if (this.sourceParser != null) this.sourceParser.problemReporter().javadocInvalidSeeReference(start, end);
 		// Reset position: we want to rescan last token
-		if (this.currentTokenType != -1) {
-			this.index = getEndPosition();
-			this.scanner.currentPosition = getEndPosition();
-			this.currentTokenType = -1;
-		}
+		this.index = this.tokenPreviousPosition;
+		this.scanner.currentPosition = this.tokenPreviousPosition;
+		this.currentTokenType = -1;
 		return null;
 	}
 
@@ -703,6 +715,11 @@
 			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;
@@ -721,9 +738,7 @@
 
 		// Scan tokens
 		int primitiveToken = -1;
-		int previousPosition = -1;
 		nextToken : for (int iToken = 0; ; iToken++) {
-			previousPosition = this.index;
 			int token = readToken();
 			switch (token) {
 				case TerminalTokens.TokenNameIdentifier :
@@ -765,8 +780,8 @@
 					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 = previousPosition;
-							this.scanner.currentPosition = previousPosition;
+							this.index = this.tokenPreviousPosition;
+							this.scanner.currentPosition = this.tokenPreviousPosition;
 							this.currentTokenType = -1;
 						}
 						throw new InvalidInputException();
@@ -776,8 +791,8 @@
 		}
 		// Reset position: we want to rescan last token
 		if (this.currentTokenType != -1) {
-			this.index = previousPosition;
-			this.scanner.currentPosition = previousPosition;
+			this.index = this.tokenPreviousPosition;
+			this.scanner.currentPosition = this.tokenPreviousPosition;
 			this.currentTokenType = -1;
 		}
 		return createTypeReference(primitiveToken);
@@ -857,6 +872,9 @@
 		// 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;
 		}
@@ -869,8 +887,8 @@
 			if (token != TerminalTokens.TokenNameLPAREN) {
 				// Reset position: we want to rescan last token
 				if (this.currentTokenType != -1) {
-					this.index = previousPosition;
-					this.scanner.currentPosition = previousPosition;
+					this.index = this.tokenPreviousPosition;
+					this.scanner.currentPosition = this.tokenPreviousPosition;
 					this.currentTokenType = -1;
 				}
 				return pushSeeRef(reference, plain);
@@ -878,6 +896,10 @@
 		} 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;
 	}
@@ -897,6 +919,10 @@
 		} 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;
 	}
 
@@ -1061,14 +1087,16 @@
 	 */
 	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.currentTokenType == TerminalTokens.TokenNameMULTIPLY) {
+			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;
 	}
@@ -1125,7 +1153,6 @@
 		} else {
 			buffer.append("<-- Scanner current position here\n===============================\n"); //$NON-NLS-1$
 		}
-		//	+ "" //$NON-NLS-1$
 		buffer.append(end);
 
 		return buffer.toString();
@@ -1142,17 +1169,21 @@
 				this.lineEnd = this.endComment;
 				return;
 			}
-			this.lineStarted= false;
 		}
 	}
 	protected abstract void updateDocComment();
 
-	/*
+	/**
 	 * Search the line number corresponding to a specific position.
-	 * See Scanner
+	 * 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;
@@ -1176,12 +1207,17 @@
 		return m+2;
 	}
 
-	/*
+	/**
 	 * Search the source position corresponding to the end of a given line number.
-	 * See Scanner
+	 * 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) 
diff --git a/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java b/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java
index 70bb4f0..e6adf1d 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java
@@ -60,11 +60,13 @@
 
 		try {
 			this.source = this.sourceParser.scanner.source;
-			this.lineEnds = this.sourceParser.scanner.getLineEnds();
 			this.index = javadocStart +3;
 			this.endComment = javadocEnd - 2;
 			if (this.checkDocComment) {
 				// Initialization
+				this.scanner.lineEnds = this.sourceParser.scanner.lineEnds;
+				this.scanner.linePtr = this.sourceParser.scanner.linePtr;
+				this.lineEnds = this.scanner.lineEnds;
 				this.docComment = new Javadoc(javadocStart, javadocEnd);
 				parseComment(javadocStart, javadocEnd);
 			} else {
diff --git a/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java b/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
index 3e74d2a..94da7ff 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
@@ -7254,9 +7254,7 @@
 			System.out.println("----------------------------------"); //$NON-NLS-1$
 		}
 	}
-	if (this.scanner.recordLineSeparator) {
-		this.compilationUnit.compilationResult.lineSeparatorPositions = this.scanner.getLineEnds();
-	}
+	persistLineSeparatorPositions();
 	for (int i = 0; i < this.scanner.foundTaskCount; i++){
 		problemReporter().task(
 			new String(this.scanner.foundTaskTags[i]), 
@@ -8524,6 +8522,11 @@
 
 	return this.expressionStack[this.expressionPtr];
 }
+public void persistLineSeparatorPositions() {
+	if (this.scanner.recordLineSeparator) {
+		this.compilationUnit.compilationResult.lineSeparatorPositions = this.scanner.getLineEnds();
+	}
+}
 /**
  * Returns this parser's problem reporter initialized with its reference context.
  * Also it is assumed that a problem is going to be reported, so initializes
diff --git a/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java b/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java
index a115af2..2995107 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java
@@ -502,23 +502,17 @@
 			//need the unicode buffer
 			if (this.withoutUnicodePtr == 0) {
 				//buffer all the entries that have been left aside....
-				this.withoutUnicodePtr = this.currentPosition - unicodeSize - this.startPosition;
-				System.arraycopy(
-					this.source, 
-					this.startPosition, 
-					this.withoutUnicodeBuffer, 
-					1, 
-					this.withoutUnicodePtr); 
+			    unicodeInitializeBuffer(this.currentPosition - unicodeSize - this.startPosition);
 			}
 			//fill the buffer with the char
-			this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+			unicodeStoreAt(++this.withoutUnicodePtr);
 			return this.currentCharacter;
 
 		} //-------------end unicode traitement--------------
 		else {
 			this.unicodeAsBackSlash = false;
 			if (this.withoutUnicodePtr != 0) {
-				this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+			    unicodeStoreAt(++this.withoutUnicodePtr);
 			}
 			return this.currentCharacter;
 		}
@@ -574,16 +568,10 @@
 			//need the unicode buffer
 			if (this.withoutUnicodePtr == 0) {
 				//buffer all the entries that have been left aside....
-				this.withoutUnicodePtr = this.currentPosition - unicodeSize - this.startPosition;
-				System.arraycopy(
-					this.source, 
-					this.startPosition, 
-					this.withoutUnicodeBuffer, 
-					1, 
-					this.withoutUnicodePtr); 
+			    unicodeInitializeBuffer(this.currentPosition - unicodeSize - this.startPosition);
 			}
 			//fill the buffer with the char
-			this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+			unicodeStoreAt(++this.withoutUnicodePtr);
 			return true;
 
 		} //-------------end unicode traitement--------------
@@ -594,7 +582,7 @@
 			}
 			this.unicodeAsBackSlash = false;
 			if (this.withoutUnicodePtr != 0)
-				this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+				unicodeStoreAt(++this.withoutUnicodePtr);
 			return true;
 		}
 	} catch (IndexOutOfBoundsException e) {
@@ -654,16 +642,10 @@
 			//need the unicode buffer
 			if (this.withoutUnicodePtr == 0) {
 				//buffer all the entries that have been left aside....
-				this.withoutUnicodePtr = this.currentPosition - unicodeSize - this.startPosition;
-				System.arraycopy(
-					this.source, 
-					this.startPosition, 
-					this.withoutUnicodeBuffer, 
-					1, 
-					this.withoutUnicodePtr); 
+				unicodeInitializeBuffer(this.currentPosition - unicodeSize - this.startPosition);
 			}
 			//fill the buffer with the char
-			this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+			unicodeStoreAt(++this.withoutUnicodePtr);
 			return result;
 		} //-------------end unicode traitement--------------
 		else {
@@ -678,7 +660,7 @@
 				}
 
 			if (this.withoutUnicodePtr != 0)
-				this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+				unicodeStoreAt(++this.withoutUnicodePtr);
 			return result;
 		}
 	} catch (IndexOutOfBoundsException e) {
@@ -730,16 +712,10 @@
 			//need the unicode buffer
 			if (this.withoutUnicodePtr == 0) {
 				//buffer all the entries that have been left aside....
-				this.withoutUnicodePtr = this.currentPosition - unicodeSize - this.startPosition;
-				System.arraycopy(
-					this.source, 
-					this.startPosition, 
-					this.withoutUnicodeBuffer, 
-					1, 
-					this.withoutUnicodePtr); 
+				unicodeInitializeBuffer(this.currentPosition - unicodeSize - this.startPosition);
 			}
 			//fill the buffer with the char
-			this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+			unicodeStoreAt(++this.withoutUnicodePtr);
 			return true;
 		} //-------------end unicode traitement--------------
 		else {
@@ -748,7 +724,7 @@
 				return false;
 			}
 			if (this.withoutUnicodePtr != 0)
-				this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+				unicodeStoreAt(++this.withoutUnicodePtr);
 			return true;
 		}
 	} catch (IndexOutOfBoundsException e) {
@@ -800,16 +776,10 @@
 			//need the unicode buffer
 			if (this.withoutUnicodePtr == 0) {
 				//buffer all the entries that have been left aside....
-				this.withoutUnicodePtr = this.currentPosition - unicodeSize - this.startPosition;
-				System.arraycopy(
-					this.source, 
-					this.startPosition, 
-					this.withoutUnicodeBuffer, 
-					1, 
-					this.withoutUnicodePtr); 
+				unicodeInitializeBuffer(this.currentPosition - unicodeSize - this.startPosition);
 			}
 			//fill the buffer with the char
-			this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+			unicodeStoreAt(++this.withoutUnicodePtr);
 			return true;
 		} //-------------end unicode traitement--------------
 		else {
@@ -818,7 +788,7 @@
 				return false;
 			}
 			if (this.withoutUnicodePtr != 0)
-				this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+				unicodeStoreAt(++this.withoutUnicodePtr);
 			return true;
 		}
 	} catch (IndexOutOfBoundsException e) {
@@ -870,16 +840,10 @@
 			//need the unicode buffer
 			if (this.withoutUnicodePtr == 0) {
 				//buffer all the entries that have been left aside....
-				this.withoutUnicodePtr = this.currentPosition - unicodeSize - this.startPosition;
-				System.arraycopy(
-					this.source, 
-					this.startPosition, 
-					this.withoutUnicodeBuffer, 
-					1, 
-					this.withoutUnicodePtr); 
+				unicodeInitializeBuffer(this.currentPosition - unicodeSize - this.startPosition);
 			}
 			//fill the buffer with the char
-			this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+		    unicodeStoreAt(++this.withoutUnicodePtr);
 			return true;
 		} //-------------end unicode traitement--------------
 		else {
@@ -889,7 +853,7 @@
 			}
 
 			if (this.withoutUnicodePtr != 0)
-				this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+			    unicodeStoreAt(++this.withoutUnicodePtr);
 			return true;
 		}
 	} catch (IndexOutOfBoundsException e) {
@@ -1163,7 +1127,7 @@
 							getNextUnicodeChar();
 						} else {
 							if (this.withoutUnicodePtr != 0) {
-								this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+								unicodeStoreAt(++this.withoutUnicodePtr);
 							}
 						}
 					}
@@ -1192,7 +1156,7 @@
 							isUnicode = true;
 						} else {
 							if (this.withoutUnicodePtr != 0) {
-								this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+								unicodeStoreAt(++this.withoutUnicodePtr);
 							}
 						}
 
@@ -1234,16 +1198,10 @@
 								escapeSize = this.currentPosition - escapeSize;
 								if (this.withoutUnicodePtr == 0) {
 									//buffer all the entries that have been left aside....
-									this.withoutUnicodePtr = this.currentPosition - escapeSize - 1 - this.startPosition;
-									System.arraycopy(
-										this.source, 
-										this.startPosition, 
-										this.withoutUnicodeBuffer, 
-										1, 
-										this.withoutUnicodePtr); 
-									this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+								    unicodeInitializeBuffer(this.currentPosition - escapeSize - 1 - this.startPosition);
+								    unicodeStoreAt(++this.withoutUnicodePtr);
 								} else { //overwrite the / in the buffer
-									this.withoutUnicodeBuffer[this.withoutUnicodePtr] = this.currentCharacter;
+								    unicodeStoreAt(this.withoutUnicodePtr);
 									if (backSlashAsUnicodeInString) { //there are TWO \ in the stream where only one is correct
 										this.withoutUnicodePtr--;
 									}
@@ -1256,7 +1214,7 @@
 								getNextUnicodeChar();
 							} else {
 								if (this.withoutUnicodePtr != 0) {
-									this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+									unicodeStoreAt(++this.withoutUnicodePtr);
 								}
 							}
 
@@ -1438,7 +1396,7 @@
 								} else {
 									isUnicode = false;
 									if (this.withoutUnicodePtr != 0) {
-										this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+										unicodeStoreAt(++this.withoutUnicodePtr);
 									}
 								}
 	
@@ -1580,16 +1538,10 @@
 			//need the unicode buffer
 			if (this.withoutUnicodePtr == 0) {
 				//buffer all the entries that have been left aside....
-				this.withoutUnicodePtr = this.currentPosition - unicodeSize - this.startPosition;
-				System.arraycopy(
-					this.source, 
-					this.startPosition, 
-					this.withoutUnicodeBuffer, 
-					1, 
-					this.withoutUnicodePtr); 
+				unicodeInitializeBuffer(this.currentPosition - unicodeSize - this.startPosition);
 			}
 			//fill the buffer with the char
-			this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+			unicodeStoreAt(++this.withoutUnicodePtr);
 		}
 		this.unicodeAsBackSlash = this.currentCharacter == '\\';
 	} catch (ArrayIndexOutOfBoundsException e) {
@@ -1653,7 +1605,7 @@
 									getNextUnicodeChar();
 								} else {
 									if (this.withoutUnicodePtr != 0) {
-										this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+										unicodeStoreAt(++this.withoutUnicodePtr);
 									}
 								}
 							} catch (InvalidInputException ex) {
@@ -1672,7 +1624,7 @@
 								getNextUnicodeChar();
 							} else {
 								if (this.withoutUnicodePtr != 0) {
-									this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+								    unicodeStoreAt(++this.withoutUnicodePtr);
 								}
 							}
 						} catch (InvalidInputException ex) {
@@ -1700,7 +1652,7 @@
 									getNextUnicodeChar();
 								} else {
 									if (this.withoutUnicodePtr != 0) {
-										this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+										unicodeStoreAt(++this.withoutUnicodePtr);
 									}
 								}
 							} catch (InvalidInputException ex) {
@@ -1849,7 +1801,7 @@
 								} else {
 									isUnicode = false;
 									if (this.withoutUnicodePtr != 0) {
-										this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+    								    unicodeStoreAt(++this.withoutUnicodePtr);
 									}
 								}
 	
@@ -1977,7 +1929,7 @@
 			return true;
 
 		//buffer the new char which is not a white space
-		this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+		unicodeStoreAt(++this.withoutUnicodePtr);
 		//this.withoutUnicodePtr == 1 is true here
 		return false;
 	} catch (IndexOutOfBoundsException e){
@@ -2404,7 +2356,7 @@
 			getNextUnicodeChar();
 		} else {
 			if (this.withoutUnicodePtr != 0) {
-				this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+				unicodeStoreAt(++this.withoutUnicodePtr);
 			}
 		}
 	} else
@@ -3071,7 +3023,7 @@
 				getNextUnicodeChar();
 			} else {
 				if (this.withoutUnicodePtr != 0) {
-					this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+					unicodeStoreAt(++this.withoutUnicodePtr);
 				}
 			}
 			if (Character.digit(this.currentCharacter, 16) == -1)
@@ -3113,7 +3065,7 @@
 						getNextUnicodeChar();
 					} else {
 						if (this.withoutUnicodePtr != 0) {
-							this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+							unicodeStoreAt(++this.withoutUnicodePtr);
 						}
 					}
 
@@ -3125,7 +3077,7 @@
 							getNextUnicodeChar();
 						} else {
 							if (this.withoutUnicodePtr != 0) {
-								this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+								unicodeStoreAt(++this.withoutUnicodePtr);
 							}
 						}
 					}
@@ -3165,7 +3117,7 @@
 			getNextUnicodeChar();
 		} else {
 			if (this.withoutUnicodePtr != 0) {
-				this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+				unicodeStoreAt(++this.withoutUnicodePtr);
 			}
 		}
 
@@ -3177,7 +3129,7 @@
 				getNextUnicodeChar();
 			} else {
 				if (this.withoutUnicodePtr != 0) {
-					this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+					unicodeStoreAt(++this.withoutUnicodePtr);
 				}
 			}
 		}
@@ -3239,7 +3191,6 @@
 	this.eofPosition = sourceLength;
 	this.initialPosition = this.currentPosition = 0;
 	this.containsAssertKeyword = false;
-	this.withoutUnicodeBuffer = new char[sourceLength]; // TODO (philippe) should only allocate when needed
 }
 
 public String toString() {
@@ -3491,4 +3442,21 @@
 			return "not-a-token"; //$NON-NLS-1$
 	}
 }
+public void unicodeInitializeBuffer(int length) {
+	this.withoutUnicodePtr = length;	
+    if (this.withoutUnicodeBuffer == null) this.withoutUnicodeBuffer = new char[length+(1+10)];
+    int bLength = this.withoutUnicodeBuffer.length;
+    if (1+length >= bLength) {
+        System.arraycopy(this.withoutUnicodeBuffer, 0, this.withoutUnicodeBuffer = new char[length + (1+10)], 0, bLength);
+    }
+	System.arraycopy(this.source, this.startPosition, this.withoutUnicodeBuffer, 1, length);    
+}
+public void unicodeStoreAt(int pos) {
+    if (this.withoutUnicodeBuffer == null) this.withoutUnicodeBuffer = new char[10];
+    int length = this.withoutUnicodeBuffer.length;
+    if (pos == length) {
+        System.arraycopy(this.withoutUnicodeBuffer, 0, this.withoutUnicodeBuffer = new char[length * 2], 0, length);
+    }
+	this.withoutUnicodeBuffer[pos] = this.currentCharacter;
+}
 }
diff --git a/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java b/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
index c25c316..fee8a5c 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
+++ b/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
@@ -2496,11 +2496,11 @@
 		statement.sourceStart,
 		statement.sourceEnd);
 }
-public void javadocAmbiguousMethodReference(FieldReference fieldRef, int modifiers) {
+public void javadocAmbiguousMethodReference(int sourceStart, int sourceEnd, Binding fieldBinding, int modifiers) {
 	int id = IProblem.JavadocAmbiguousMethodReference;
 	if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) {
-		String[] arguments = new String[] {new String(fieldRef.binding.readableName())};
-		handle(id, arguments, arguments, fieldRef.sourceStart, fieldRef.sourceEnd);
+		String[] arguments = new String[] {new String(fieldBinding.readableName())};
+		handle(id, arguments, arguments, sourceStart, sourceEnd);
 	}
 }
 /*
@@ -2510,10 +2510,9 @@
  * 	- NonStaticReferenceInConstructorInvocation :
  * 	- ReceiverTypeNotVisible :
  */
-public void javadocInvalidField(FieldReference fieldRef, TypeBinding searchedType, int modifiers) {
+public void javadocInvalidField(int sourceStart, int sourceEnd, Binding fieldBinding, TypeBinding searchedType, int modifiers) {
 	int id = IProblem.JavadocUndefinedField;
-	FieldBinding field = fieldRef.binding;
-	switch (field.problemId()) {
+	switch (fieldBinding.problemId()) {
 		case NotFound :
 			id = IProblem.JavadocUndefinedField;
 			break;
@@ -2533,8 +2532,8 @@
 	}
 
 	if (javadocVisibility(this.options.reportInvalidJavadocTagsVisibility, modifiers)) {
-		String[] arguments = new String[] {new String(field.readableName())};
-		handle(id, arguments, arguments, fieldRef.sourceStart, fieldRef.sourceEnd);
+		String[] arguments = new String[] {new String(fieldBinding.readableName())};
+		handle(id, arguments, arguments, sourceStart, sourceEnd);
 	}
 }
 /*
diff --git a/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties b/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
index 8295a36..7f537dd 100644
--- a/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
+++ b/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
@@ -232,7 +232,7 @@
 321 = The package {0} collides with a type
 322 = The type {1} collides with a package
 323 = The type {1} is already defined
-324 = The type {0} cannot be resolved. It is indirectly referenced from required .class files.
+324 = The type {0} cannot be resolved. It is indirectly referenced from required .class files
 325 = The public type {1} must be defined in its own file
 326 = A package must be specified in {0} or a default package created
 327 = The hierarchy of the type {0} is inconsistent
diff --git a/dom/org/eclipse/jdt/core/dom/AST.java b/dom/org/eclipse/jdt/core/dom/AST.java
index f358adf..ac5ba52 100644
--- a/dom/org/eclipse/jdt/core/dom/AST.java
+++ b/dom/org/eclipse/jdt/core/dom/AST.java
@@ -231,6 +231,7 @@
 	 * @param options compiler options
 	 * @param monitor the progress monitor used to report progress and request cancelation,
 	 *     or <code>null</code> if none
+	 * @param isResolved whether the given compilation unit declaration is resolved
 	 * @return the compilation unit node
 	 */
 	public static CompilationUnit convertCompilationUnit(
@@ -238,13 +239,14 @@
 		org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration compilationUnitDeclaration,
 		char[] source,
 		Map options,
+		boolean isResolved,
 		IProgressMonitor monitor) {
 		
-		ASTConverter converter = new ASTConverter(options, true, monitor);
+		ASTConverter converter = new ASTConverter(options, isResolved, monitor);
 		AST ast = AST.newAST(level);
 		int savedDefaultNodeFlag = ast.getDefaultNodeFlag();
 		ast.setDefaultNodeFlag(ASTNode.ORIGINAL);
-		BindingResolver resolver = new DefaultBindingResolver(compilationUnitDeclaration.scope);
+		BindingResolver resolver = isResolved ? new DefaultBindingResolver(compilationUnitDeclaration.scope) : new BindingResolver();
 		ast.setBindingResolver(resolver);
 		converter.setAST(ast);
 	
@@ -263,9 +265,9 @@
 	 *    indicates source compatibility mode (as per <code>JavaCore</code>);
 	 *    <code>"1.3"</code> means the source code is as per JDK 1.3;
 	 *    <code>"1.4"</code> means the source code is as per JDK 1.4
-	 *    (<code>"assert"</code> is a now a keyword);
+	 *    (<code>"assert"</code> is now a keyword);
 	 *    <code>"1.5"</code> means the source code is as per JDK 1.5
-	 *    (<code>"enum"</code> is a now a keyword);
+	 *    (<code>"enum"</code> is now a keyword);
 	 *    additional legal values may be added later. </li>
 	 * </ul>
 	 * Options other than the above are ignored.
diff --git a/dom/org/eclipse/jdt/core/dom/ASTConverter.java b/dom/org/eclipse/jdt/core/dom/ASTConverter.java
index 95b4c54..08ac72d 100644
--- a/dom/org/eclipse/jdt/core/dom/ASTConverter.java
+++ b/dom/org/eclipse/jdt/core/dom/ASTConverter.java
@@ -54,6 +54,7 @@
 	protected Set pendingThisExpressionScopeResolution;
 	protected boolean resolveBindings;
 	Scanner scanner;
+	private DefaultCommentMapper commentMapper;
 
 	public ASTConverter(Map options, boolean resolveBindings, IProgressMonitor monitor) {
 		this.resolveBindings = resolveBindings;
@@ -876,7 +877,7 @@
 		CastExpression castExpression = this.ast.newCastExpression();
 		castExpression.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
 		org.eclipse.jdt.internal.compiler.ast.Expression type = expression.type;
-		removeExtraBlanks(type);
+		trimWhiteSpacesAndComments(type);
 		if (type instanceof org.eclipse.jdt.internal.compiler.ast.TypeReference ) {
 			castExpression.setType(convertType((org.eclipse.jdt.internal.compiler.ast.TypeReference)type));
 		} else if (type instanceof org.eclipse.jdt.internal.compiler.ast.NameReference) {
@@ -1401,8 +1402,10 @@
 	public void convert(org.eclipse.jdt.internal.compiler.ast.Javadoc javadoc, BodyDeclaration bodyDeclaration) {
 		if (bodyDeclaration.getJavadoc() == null) {
 			if (javadoc != null) {
-				DefaultCommentMapper mapper = new DefaultCommentMapper(this.commentsTable);
-				Comment comment = mapper.getComment(javadoc.sourceStart);
+				if (this.commentMapper == null || !this.commentMapper.hasSameTable(this.commentsTable)) {
+					this.commentMapper = new DefaultCommentMapper(this.commentsTable);
+				}
+				Comment comment = this.commentMapper.getComment(javadoc.sourceStart);
 				if (comment != null && comment.isDocComment() && comment.getParent() == null) {
 					Javadoc docComment = (Javadoc) comment;
 					if (this.resolveBindings) {
@@ -2134,7 +2137,7 @@
 		}
 		parenthesizedExpression.setSourceRange(expression.sourceStart, expression.sourceEnd - expression.sourceStart + 1);
 		adjustSourcePositionsForParent(expression);
-		removeExtraBlanks(expression);
+		trimWhiteSpacesAndComments(expression);
 		// decrement the number of parenthesis
 		int numberOfParenthesis = (expression.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK) >> org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedSHIFT;
 		expression.bits &= ~org.eclipse.jdt.internal.compiler.ast.ASTNode.ParenthesizedMASK;
@@ -2752,9 +2755,9 @@
 	}
 	
 	/**
-	 * Remove whitespaces before and after the expression.
+	 * Remove whitespaces and comments before and after the expression.
 	 */	
-	protected void removeExtraBlanks(org.eclipse.jdt.internal.compiler.ast.Expression expression) {
+	private void trimWhiteSpacesAndComments(org.eclipse.jdt.internal.compiler.ast.Expression expression) {
 		int start = expression.sourceStart;
 		int end = expression.sourceEnd;
 		int token;
@@ -2768,11 +2771,17 @@
 			while (true) {
 				token = removeBlankScanner.getNextToken();
 				switch (token) {
+					case TerminalTokens.TokenNameCOMMENT_JAVADOC :
+					case TerminalTokens.TokenNameCOMMENT_LINE :
+					case TerminalTokens.TokenNameCOMMENT_BLOCK :
+						if (first) {
+							trimLeftPosition = removeBlankScanner.currentPosition;
+						}
+						break;
 					case TerminalTokens.TokenNameWHITESPACE :
 						if (first) {
 							trimLeftPosition = removeBlankScanner.currentPosition;
 						}
-						trimRightPosition = removeBlankScanner.startPosition - 1;
 						break;
 					case TerminalTokens.TokenNameEOF :
 						expression.sourceStart = trimLeftPosition;
@@ -2780,12 +2789,13 @@
 						return;
 					default :
 						/*
-						 * if we find something else than a whitespace, then we reset the trimRigthPosition
-						 * to the expression source end.
+						 * if we find something else than a whitespace or a comment,
+						 * then we reset the trimRigthPosition to the expression
+						 * source end.
 						 */
-						trimRightPosition = expression.sourceEnd;
+						trimRightPosition = removeBlankScanner.currentPosition - 1;
+						first = false;				
 				}
-				first = false;
 			}
 		} catch (InvalidInputException e){
 			// ignore
diff --git a/dom/org/eclipse/jdt/core/dom/ASTParser.java b/dom/org/eclipse/jdt/core/dom/ASTParser.java
index 4e965e6..7d2593b 100644
--- a/dom/org/eclipse/jdt/core/dom/ASTParser.java
+++ b/dom/org/eclipse/jdt/core/dom/ASTParser.java
@@ -644,6 +644,9 @@
 					if (source == null) {
 						throw new IllegalStateException();
 					}
+					if (this.sourceLength == -1) {
+						this.sourceLength = source.length;
+					}
 					if (this.partial) {
 						searcher = new NodeSearcher(this.focalPointPosition);
 					}
@@ -805,6 +808,9 @@
 		converter.setAST(ast);
 		CodeSnippetParsingUtil codeSnippetParsingUtil = new CodeSnippetParsingUtil();
 		CompilationUnit compilationUnit = ast.newCompilationUnit();
+		if (this.sourceLength == -1) {
+			this.sourceLength = this.rawSource.length;
+		}
 		switch(this.astKind) {
 			case K_STATEMENTS :
 				ConstructorDeclaration constructorDeclaration = codeSnippetParsingUtil.parseStatements(this.rawSource, this.sourceOffset, this.sourceLength, this.compilerOptions, true);
diff --git a/dom/org/eclipse/jdt/core/dom/DefaultCommentMapper.java b/dom/org/eclipse/jdt/core/dom/DefaultCommentMapper.java
index 28cf852..eef1ebe 100644
--- a/dom/org/eclipse/jdt/core/dom/DefaultCommentMapper.java
+++ b/dom/org/eclipse/jdt/core/dom/DefaultCommentMapper.java
@@ -10,10 +10,7 @@
  *******************************************************************************/
 package org.eclipse.jdt.core.dom;
 
-import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
 
 import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.core.compiler.InvalidInputException;
@@ -26,11 +23,11 @@
  * @since 3.0
  */
 class DefaultCommentMapper {
-	private Comment[] comments;
-	private Map leadingComments;
-	private Map trailingComments;
+	Comment[] comments;
+	HashMap leadingComments;
+	HashMap trailingComments;
 	
-	private int commentIndex;
+	Scanner scanner;
 
 	/**
 	 * @param table the given table of comments
@@ -39,6 +36,10 @@
 		this.comments = table;
 	}
 
+	boolean hasSameTable(Comment[] table) {
+		return this.comments == table;
+	}
+
 	/**
 	 * Get comment of the list which includes a given position
 	 * 
@@ -168,11 +169,18 @@
 		if (this.trailingComments != null) {
 			int[] range = (int[]) this.trailingComments.get(node);
 			if (range != null) {
-				Comment lastComment = this.comments[range[1]];
-				end = lastComment.getStartPosition() + lastComment.getLength();
+				if (range[0] == -1 && range[1] == -1) {
+					ASTNode parent = node.getParent();
+					if (parent != null) {
+						return getExtendedEnd(parent);
+					}
+				} else {
+					Comment lastComment = this.comments[range[1]];
+					end = lastComment.getStartPosition() + lastComment.getLength();
+				}
 			}
 		}
-		return end;
+		return end-1;
 	}
 
 	/**
@@ -189,7 +197,7 @@
 	 * @since 3.0
 	 */
 	public int getExtendedLength(ASTNode node) {
-		return getExtendedEnd(node) - getExtendedStartPosition(node);
+		return getExtendedEnd(node) - getExtendedStartPosition(node) + 1;
 	}
 
 	/*
@@ -198,7 +206,7 @@
 	 * Scanner is necessary to scan between nodes and comments and verify if there's
 	 * nothing else than white spaces.
 	 */
-	void initialize(CompilationUnit unit, Scanner scanner) {
+	void initialize(CompilationUnit unit, Scanner sc) {
 		
 		// Init comments
 		this.comments = unit.optionalCommentTable;
@@ -215,52 +223,13 @@
 		this.trailingComments = new HashMap();
 		
 		// Init scanner and start ranges computing
-		scanner.linePtr = scanner.lineEnds.length-1;
-		scanner.tokenizeWhiteSpace = true;
-		doExtraRangesForChildren(unit, scanner);
-	}
-
-	/*
-	 * Compute extended ranges for children of a given node.
-	 * Note that previous end for first child is naturally the node starting position
-	 * end next start for last child is the first token after the end of the node which
-	 * is neither a comment nor white spaces.
-	 * 
-	 * Compute first leading and trailing comment tables as this let us to optimize
-	 * comment look up in the table. As all comments on a same level are ordered
-	 * by position, we store the index to start the search from it instead of restarting
-	 * each time from the beginning (see in storeLeadingComments and storeTrailingComments
-	 * methods).
-	 */
-	private void doExtraRangesForChildren(ASTNode node, Scanner scanner) {
-		// Compute node children
-		List children= getChildren(node);
-		int size = children.size() ;
+		this.scanner = sc;
+		this.scanner.linePtr = this.scanner.lineEnds.length-1;
+		this.scanner.tokenizeWhiteSpace = true;
 		
-		// Compute last next start and previous end. Next start is the starting position
-		// of first token following node end which is neither a comment nor white spaces.
-		int lastPos = getExtendedEnd(node);
-		int previousEnd = node.getStartPosition();
-		
-		// Compute leading and trailing comments for all children nodes at this level
-		this.commentIndex = 0;
-		try {
-			for (int i= 0; i < size; i++) {
-				ASTNode current = (ASTNode) children.get(i);
-				boolean lastChild = i==(size-1);
-				int nextStart = lastChild ? lastPos : ((ASTNode) children.get(i+1)).getStartPosition();
-				storeLeadingComments(current, previousEnd,scanner);
-				previousEnd = storeTrailingComments(current, nextStart, scanner, lastChild);
-			}
-		}
-		catch (Exception ex) {
-			// Give up extended ranges at this level if unexpected exception happens...
-		}
-		
-		// Compute extended ranges at sub-levels
-		for (int i= 0; i < size; i++) {
-			doExtraRangesForChildren((ASTNode) children.get(i), scanner);
-		}
+		// Start unit visit
+		DefaultASTVisitor commentVisitor = new CommentMapperVisitor();
+		unit.accept(commentVisitor);
 	}
 
 	/**
@@ -285,17 +254,17 @@
 	 * If finally there is a subset of comments, then store start and end indexes 
 	 * in leading comments table.
 	 */
-	int storeLeadingComments(ASTNode node, int previousEnd, Scanner scanner) {
+	int storeLeadingComments(ASTNode node, int previousEnd) {
 		// Init extended position
 		int nodeStart = node.getStartPosition();
 		int extended = nodeStart;
 		
 		// Get line of node start position
-		int previousEndLine = scanner.getLineNumber(previousEnd);
-		int nodeStartLine = scanner.getLineNumber(nodeStart);
+		int previousEndLine = this.scanner.getLineNumber(previousEnd);
+		int nodeStartLine = this.scanner.getLineNumber(nodeStart);
 		
 		// Find first comment index
-		int idx = getCommentIndex(this.commentIndex, nodeStart, -1);
+		int idx = getCommentIndex(0, nodeStart, -1);
 		if (idx == -1) {
 			return nodeStart;
 		}
@@ -309,15 +278,15 @@
 			Comment comment = this.comments[idx];
 			int commentStart = comment.getStartPosition();
 			int end = commentStart+comment.getLength()-1;
-			int commentLine = scanner.getLineNumber(commentStart);
+			int commentLine = this.scanner.getLineNumber(commentStart);
 			if (end <= previousEnd || (commentLine == previousEndLine && commentLine != nodeStartLine)) {
 				// stop search on condition 1) and 2)
 				break;
 			} else if ((end+1) < previousStart) { // may be equals => then no scan is necessary
-				scanner.resetTo(end+1, previousStart);
+				this.scanner.resetTo(end+1, previousStart);
 				try {
-					int token = scanner.getNextToken();
-					if (token != TerminalTokens.TokenNameWHITESPACE || scanner.currentPosition != previousStart) {
+					int token = this.scanner.getNextToken();
+					if (token != TerminalTokens.TokenNameWHITESPACE || this.scanner.currentPosition != previousStart) {
 						// stop search on condition 3)
 						// if first comment fails, then there's no extended position in fact
 						if (idx == endIdx) {
@@ -330,7 +299,7 @@
 					return nodeStart;
 				}
 				// verify that there's no more than one line between node/comments
-				char[] gap = scanner.getCurrentIdentifierSource();
+				char[] gap = this.scanner.getCurrentIdentifierSource();
 				int nbrLine = 0;
 				int pos = -1;
 				while ((pos=CharOperation.indexOf('\n', gap,pos+1)) >= 0) {
@@ -350,19 +319,19 @@
 			int commentStart = this.comments[startIdx].getStartPosition();
 			if (previousEnd < commentStart && previousEndLine != nodeStartLine) {
 				int lastTokenEnd = previousEnd;
-				scanner.resetTo(previousEnd, commentStart);
+				this.scanner.resetTo(previousEnd, commentStart);
 				try {
-					while (scanner.currentPosition != commentStart) {
-						if (scanner.getNextToken() != TerminalTokens.TokenNameWHITESPACE) {
-							lastTokenEnd =  scanner.getCurrentTokenEndPosition();
+					while (this.scanner.currentPosition != commentStart) {
+						if (this.scanner.getNextToken() != TerminalTokens.TokenNameWHITESPACE) {
+							lastTokenEnd =  this.scanner.getCurrentTokenEndPosition();
 						}
 					}
 				} catch (InvalidInputException e) {
 					// do nothing
 				}
-				int lastTokenLine = scanner.getLineNumber(lastTokenEnd);
+				int lastTokenLine = this.scanner.getLineNumber(lastTokenEnd);
 				int length = this.comments.length;
-				while (startIdx<length && lastTokenLine == scanner.getLineNumber(this.comments[startIdx].getStartPosition()) && nodeStartLine != lastTokenLine) {
+				while (startIdx<length && lastTokenLine == this.scanner.getLineNumber(this.comments[startIdx].getStartPosition()) && nodeStartLine != lastTokenLine) {
 					startIdx++;
 				}
 			}
@@ -370,7 +339,6 @@
 			if (startIdx <= endIdx) {
 				this.leadingComments.put(node, new int[] { startIdx, endIdx });
 				extended = this.comments[endIdx].getStartPosition();
-				this.commentIndex = endIdx;
 			}
 		}
 		return extended;
@@ -398,16 +366,22 @@
 	 * If finally there is a subset of comments, then store start and end indexes 
 	 * in trailing comments table.
 	 */
-	int storeTrailingComments(ASTNode node, int nextStart, Scanner scanner, boolean lastChild) {
+	int storeTrailingComments(ASTNode node, int nextStart,  boolean lastChild) {
+
 		// Init extended position
 		int nodeEnd = node.getStartPosition()+node.getLength()-1;
+		if (nodeEnd == nextStart) {
+			// special case for last child of its parent
+			this.trailingComments.put(node, new int[] { -1, -1 });
+			return nodeEnd;
+		}
 		int extended = nodeEnd;
 		
 		// Get line number
-		int nodeEndLine = scanner.getLineNumber(nodeEnd);
+		int nodeEndLine = this.scanner.getLineNumber(nodeEnd);
 		
 		// Find comments range index
-		int idx = getCommentIndex(this.commentIndex, nodeEnd, 1);
+		int idx = getCommentIndex(0, nodeEnd, 1);
 		if (idx == -1) {
 			return nodeEnd;
 		}
@@ -428,10 +402,10 @@
 				// stop search on condition 1)
 				break;
 			} else if (previousEnd < commentStart) {
-				scanner.resetTo(previousEnd, commentStart);
+				this.scanner.resetTo(previousEnd, commentStart);
 				try {
-					int token = scanner.getNextToken();
-					if (token != TerminalTokens.TokenNameWHITESPACE || scanner.currentPosition != commentStart) {
+					int token = this.scanner.getNextToken();
+					if (token != TerminalTokens.TokenNameWHITESPACE || this.scanner.currentPosition != commentStart) {
 						// stop search on condition 2)
 						// if first index fails, then there's no extended position in fact...
 						if (idx == startIdx) {
@@ -445,7 +419,7 @@
 					return nodeEnd;
 				}
 				// verify that there's no more than one line between node/comments
-				char[] gap = scanner.getCurrentIdentifierSource();
+				char[] gap = this.scanner.getCurrentIdentifierSource();
 				int nbrLine = 0;
 				int pos = -1;
 				while ((pos=CharOperation.indexOf('\n', gap,pos+1)) >= 0) {
@@ -457,7 +431,7 @@
 				}
 			}
 			// Store index if we're on the same line than node end
-			int commentLine = scanner.getLineNumber(commentStart);
+			int commentLine = this.scanner.getLineNumber(commentStart);
 			if (commentLine == nodeEndLine) {
 				sameLineIdx = idx;
 			}
@@ -468,8 +442,8 @@
 		if (endIdx != -1) {
 			// Verify that following node start is separated
 			if (!lastChild) {
-				int nextLine = scanner.getLineNumber(nextStart);
-				int previousLine = scanner.getLineNumber(previousEnd);
+				int nextLine = this.scanner.getLineNumber(nextStart);
+				int previousLine = this.scanner.getLineNumber(previousEnd);
 				if((nextLine - previousLine) <= 1) {
 					if (sameLineIdx == -1) return nodeEnd;
 					endIdx = sameLineIdx;
@@ -478,36 +452,61 @@
 			// Store trailing comments indexes
 			this.trailingComments.put(node, new int[] { startIdx, endIdx });
 			extended = this.comments[endIdx].getStartPosition()+this.comments[endIdx].getLength()-1;
-			this.commentIndex = endIdx;
 		}
 		return extended;
 	}
-	
-	/**
-	 * Returns a list of the direct chidrens of a node. The siblings are ordered by start offset.
-	 * @param node
-	 * @return
-	 */    
-	private List getChildren(ASTNode node) {
-		ChildrenCollector visitor= new ChildrenCollector();
-		node.accept(visitor);
-		return visitor.result;		
-	}
 
-	private class ChildrenCollector extends DefaultASTVisitor {
-		public List result;
+	class CommentMapperVisitor extends DefaultASTVisitor {
 
-		public ChildrenCollector() {
-			super();
-			this.result= null;
-		}
+		HashMap waitingSiblings = new HashMap(10);
+
 		protected boolean visitNode(ASTNode node) {
-			if (this.result == null) { // first visitNode: on the node's parent: do nothing, return true
-				this.result= new ArrayList();
-				return true;
+
+			// Get default previous end
+			ASTNode parent = node.getParent();
+			int previousEnd = parent.getStartPosition();
+
+			// Look for sibling node
+			ASTNode sibling = (ASTNode) this.waitingSiblings.get(parent);
+			if (sibling != null) {
+				// Found one previous sibling, so compute its trailing comments using current node start position
+				try {
+					previousEnd = storeTrailingComments(sibling, node.getStartPosition(), false);
+				} catch (Exception ex) {
+					// Give up extended ranges at this level if unexpected exception happens...
+				}
 			}
-			this.result.add(node);
-			return false;
+
+			// Compute leading comments for current node
+			try {
+				storeLeadingComments(node, previousEnd);
+			} catch (Exception ex) {
+				// Give up extended ranges at this level if unexpected exception happens...
+			}
+			
+			// Store current node as waiting sibling for its parent
+			this.waitingSiblings.put(parent, node);
+
+			// We're always ok to visit sub-levels
+			return true;
+		}
+		
+		protected void endVisitNode(ASTNode node) {
+
+			// Look if a child node is waiting for trailing comments computing
+			ASTNode sibling = (ASTNode) this.waitingSiblings.get(node);
+			if (sibling != null) {
+				try {
+					storeTrailingComments(sibling, node.getStartPosition()+node.getLength()-1, true);
+				} catch (Exception ex) {
+					// Give up extended ranges at this level if unexpected exception happens...
+				}
+			}
+		}
+
+		public boolean visit ( CompilationUnit node) {
+			// do nothing special, just go down in sub-levels
+			return true;
 		}
 	}
 }
diff --git a/dom/org/eclipse/jdt/core/dom/EnumDeclaration.java b/dom/org/eclipse/jdt/core/dom/EnumDeclaration.java
index 73fadfd..4afa0c1 100644
--- a/dom/org/eclipse/jdt/core/dom/EnumDeclaration.java
+++ b/dom/org/eclipse/jdt/core/dom/EnumDeclaration.java
@@ -88,6 +88,7 @@
 		addProperty(JAVADOC_PROPERTY);
 		addProperty(MODIFIERS2_PROPERTY);
 		addProperty(NAME_PROPERTY);
+		addProperty(SUPER_INTERFACE_TYPES_PROPERTY);
 		addProperty(BODY_DECLARATIONS_PROPERTY);
 		PROPERTY_DESCRIPTORS = reapPropertyList();
 	}
diff --git a/eval/org/eclipse/jdt/internal/eval/CodeSnippetScope.java b/eval/org/eclipse/jdt/internal/eval/CodeSnippetScope.java
index 55c5719..bb124c3 100644
--- a/eval/org/eclipse/jdt/internal/eval/CodeSnippetScope.java
+++ b/eval/org/eclipse/jdt/internal/eval/CodeSnippetScope.java
@@ -285,7 +285,7 @@
 		if (canBeSeenByForCodeSnippet(field, currentType, invocationSite, this))
 			return field;
 		else
-			return new ProblemFieldBinding(field.declaringClass, fieldName, NotVisible);
+			return new ProblemFieldBinding(field /* closest match*/, field.declaringClass, fieldName, NotVisible);
 	}
 
 	// collect all superinterfaces of receiverType until the field is found in a supertype
@@ -504,7 +504,7 @@
 			return new ProblemMethodBinding(methodBinding, selector, argumentTypes, NotFound);
 	    methodBinding = compatibleMethod;
 		if (!canBeSeenByForCodeSnippet(methodBinding, receiverType, invocationSite, this))
-			return new ProblemMethodBinding(selector, methodBinding.parameters, methodBinding.declaringClass, NotVisible);
+			return new ProblemMethodBinding(methodBinding, selector, methodBinding.parameters, NotVisible);
 	}
 	return methodBinding;
 }
@@ -646,7 +646,7 @@
 		return visible[0];
 	}
 	if (visibleIndex == 0) {
-		return new ProblemMethodBinding(ConstructorDeclaration.ConstantPoolName, compatible[0].parameters, NotVisible);
+		return new ProblemMethodBinding(compatible[0], ConstructorDeclaration.ConstantPoolName, compatible[0].parameters, NotVisible);
 	}
 	return mostSpecificClassMethodBinding(visible, visibleIndex, invocationSite);
 }
@@ -725,15 +725,15 @@
 				    methodBinding = compatibleMethod;
 				    if (!canBeSeenByForCodeSnippet(methodBinding, receiverType, invocationSite, this)) {	
 						// using <classScope> instead of <this> for visibility check does grant all access to innerclass
-						fuzzyProblem = new ProblemMethodBinding(selector, argumentTypes, methodBinding.declaringClass, NotVisible);
+						fuzzyProblem = new ProblemMethodBinding(methodBinding, selector, argumentTypes, NotVisible);
 				    }
 				}
 			}
 			if (fuzzyProblem == null && !methodBinding.isStatic()) {
 				if (insideConstructorCall) {
-					insideProblem = new ProblemMethodBinding(methodBinding.selector, methodBinding.parameters, NonStaticReferenceInConstructorInvocation);
+					insideProblem = new ProblemMethodBinding(methodBinding, methodBinding.selector, methodBinding.parameters, NonStaticReferenceInConstructorInvocation);
 				} else if (insideStaticContext) {
-					insideProblem = new ProblemMethodBinding(methodBinding.selector, methodBinding.parameters, NonStaticReferenceInStaticContext);
+					insideProblem = new ProblemMethodBinding(methodBinding, methodBinding.selector, methodBinding.parameters, NonStaticReferenceInStaticContext);
 				}
 			}
 			if (receiverType == methodBinding.declaringClass || (receiverType.getMethods(selector)) != NoMethods) {
@@ -750,7 +750,7 @@
 				// if a method was found, complain when another is found in an 'immediate' enclosing type (ie. not inherited)
 				// NOTE: Unlike fields, a non visible method hides a visible method
 				if (foundMethod.declaringClass != methodBinding.declaringClass) // ie. have we found the same method - do not trust field identity yet
-					return new ProblemMethodBinding(methodBinding.selector, methodBinding.parameters, InheritedNameHidesEnclosingName);
+					return new ProblemMethodBinding(methodBinding, methodBinding.selector, methodBinding.parameters, InheritedNameHidesEnclosingName);
 			}
 		}
 
diff --git a/eval/org/eclipse/jdt/internal/eval/CodeSnippetToCuMapper.java b/eval/org/eclipse/jdt/internal/eval/CodeSnippetToCuMapper.java
index 5dcf7f3..d007842 100644
--- a/eval/org/eclipse/jdt/internal/eval/CodeSnippetToCuMapper.java
+++ b/eval/org/eclipse/jdt/internal/eval/CodeSnippetToCuMapper.java
@@ -286,8 +286,8 @@
 		public void acceptInterface(char[] packageName, char[] interfaceName, boolean needQualification) {
 			originalRequestor.acceptInterface(packageName, interfaceName, needQualification);
 		}
-		public void acceptMethod(char[] declaringTypePackageName, char[] declaringTypeName, char[] selector, char[][] parameterPackageNames, char[][] parameterTypeNames, boolean isConstructor) {
-			originalRequestor.acceptMethod(declaringTypePackageName, declaringTypeName, selector, parameterPackageNames, parameterTypeNames, isConstructor);
+		public void acceptMethod(char[] declaringTypePackageName, char[] declaringTypeName, char[] selector, char[][] parameterPackageNames, char[][] parameterTypeNames, boolean isConstructor, boolean isDeclaration, int start, int end) {
+			originalRequestor.acceptMethod(declaringTypePackageName, declaringTypeName, selector, parameterPackageNames, parameterTypeNames, isConstructor, isDeclaration, start, end);
 		}
 		public void acceptPackage(char[] packageName) {
 			originalRequestor.acceptPackage(packageName);
diff --git a/formatter/org/eclipse/jdt/core/formatter/CodeFormatter.java b/formatter/org/eclipse/jdt/core/formatter/CodeFormatter.java
index 68d3dc6..f44709f 100644
--- a/formatter/org/eclipse/jdt/core/formatter/CodeFormatter.java
+++ b/formatter/org/eclipse/jdt/core/formatter/CodeFormatter.java
@@ -13,7 +13,7 @@
 import org.eclipse.text.edits.TextEdit;
 
 /**
- * Specification for a generic source code formatter. This is still subject to change.
+ * Specification for a generic source code formatter.
  * 
  * @since 3.0
  */
diff --git a/formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java b/formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java
index 3b4c6d7..8906948 100644
--- a/formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java
+++ b/formatter/org/eclipse/jdt/core/formatter/DefaultCodeFormatterConstants.java
@@ -17,7 +17,8 @@
 import org.eclipse.jdt.internal.formatter.align.Alignment;
 
 /**
- * This is still subject to changes before 3.0.
+ * Constants used to set up the options of the code formatter.
+ * 
  * @since 3.0
  */
 public class DefaultCodeFormatterConstants {
@@ -2158,20 +2159,6 @@
 	public static final String FORMATTER_NUMBER_OF_EMPTY_LINES_TO_PRESERVE = JavaCore.PLUGIN_ID + ".formatter.number_of_empty_lines_to_preserve";	//$NON-NLS-1$
 	/**
 	 * <pre>
-	 * FORMATTER / Option to specify whether or not user line breaks should be preserved
-	 *     - option id:         "org.eclipse.jdt.core.formatter.preserve_user_linebreaks"
-	 *     - possible values:   { TRUE, FALSE }
-	 *     - default:           FALSE
-	 * </pre>
-	 * @see #TRUE
-	 * @see #FALSE
-	 * @since 3.0
-	 * @deprecated Will be removed
-	 */
-	public static final String FORMATTER_PRESERVE_USER_LINEBREAKS = JavaCore.PLUGIN_ID + ".formatter.preserve_user_linebreaks";//$NON-NLS-1$
-
-	/**
-	 * <pre>
 	 * FORMATTER / Option to specify whether or not empty statement should be on a new line
 	 *     - option id:         "org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line"
 	 *     - possible values:   { TRUE, FALSE }
@@ -2217,20 +2204,19 @@
 	public static final String FORMATTER_TAB_SIZE = JavaCore.PLUGIN_ID + ".formatter.tabulation.size"; //$NON-NLS-1$
 
 	/**
-	 * <p>Returns the default settings.</p>
+	 * Returns the formatter settings that most closely approximate
+	 * the default formatter settings of Eclipse version 2.1.
 	 * 
-	 * <p>This is subject to change before 3.0.</p>
-	 * @return the default settings
+	 * @return the Eclipse 2.1 settings
 	 * @since 3.0
 	 */
-	public static Map getDefaultSettings() {
+	public static Map getEclipse21Settings() {
 		return DefaultCodeFormatterOptions.getDefaultSettings().getMap();
 	}
 
 	/**
-	 * <p>Returns the settings according to the Java conventions.</p>
+	 * Returns the settings according to the Java conventions.
 	 * 
-	 * <p>This is subject to change before 3.0.</p>
 	 * @return the settings according to the Java conventions
 	 * @since 3.0
 	 */
@@ -2239,25 +2225,6 @@
 	}
 
 	/**
-	 * @deprecated use getForceWrapping(String value) instead
-	 * @param options the given options
-	 * @param key the given key
-	 * @return true if the given options is force, false otherwise
-	 */
-	public static boolean getForceWrapping(Map options, String key) {
-		Object option = options.get(key);
-		if (option != null) {
-			try {
-				int existingValue = Integer.parseInt((String) option);
-				return (existingValue & Alignment.M_FORCE) != 0;
-			} catch (NumberFormatException e) {
-				// nothing to do
-			}
-		}
-		return false;
-	}
-	
-	/**
 	 * <p>Return the force value of the given alignment value.
 	 * The given alignment value should be created using the <code>createAlignmentValue(boolean, int, int)</code>
 	 * API.
@@ -2280,31 +2247,6 @@
 			throw WRONG_ARGUMENT;
 		}
 	}
-
-	/**
-	 * @deprecated use getIndentStyle(String value) instead
-	 * @param options the given options
-	 * @param key the given key
-	 * @return the indent style
-	 */
-	public static int getIndentStyle(Map options, String key) {
-		Object option = options.get(key);
-		if (option != null) {
-			try {
-				int existingValue = Integer.parseInt((String) option);
-				if ((existingValue & Alignment.M_INDENT_BY_ONE) != 0) {
-					return INDENT_BY_ONE;
-				} else if ((existingValue & Alignment.M_INDENT_ON_COLUMN) != 0) {
-					return INDENT_ON_COLUMN;
-				} else {
-					return INDENT_DEFAULT;
-				}
-			} catch (NumberFormatException e) {
-				// nothing to do
-			}
-		}
-		return INDENT_DEFAULT;
-	}
 	
 	/**
 	 * <p>Return the indentation style of the given alignment value.
@@ -2335,37 +2277,6 @@
 			throw WRONG_ARGUMENT;
 		}
 	}
-	
-	/**
-	 * @deprecated Use getWrappingStyle(String value) instead
-	 * @param options the given options
-	 * @param key the given key
-	 * @return the wrapping style
-	 */
-	public static int getWrappingStyle(Map options, String key) {
-		Object option = options.get(key);
-		if (option != null) {
-			try {
-				int existingValue = Integer.parseInt((String) option) & Alignment.SPLIT_MASK;
-				switch(existingValue) {
-					case Alignment.M_COMPACT_SPLIT :
-						return WRAP_COMPACT;
-					case Alignment.M_COMPACT_FIRST_BREAK_SPLIT :
-						return WRAP_COMPACT_FIRST_BREAK;
-					case Alignment.M_NEXT_PER_LINE_SPLIT :
-						return WRAP_NEXT_PER_LINE;
-					case Alignment.M_NEXT_SHIFTED_SPLIT :
-						return WRAP_NEXT_SHIFTED;
-					case Alignment.M_ONE_PER_LINE_SPLIT :
-						return WRAP_ONE_PER_LINE;
-				}
-			} catch (NumberFormatException e) {
-				// nothing to do
-			}
-		}
-		return WRAP_NO_SPLIT;
-	}
-	
 	/**
 	 * <p>Return the wrapping style of the given alignment value.
 	 * The given alignment value should be created using the <code>createAlignmentValue(boolean, int, int)</code>
@@ -2404,33 +2315,6 @@
 	}
 	
 	/**
-	 * @deprecated Use setIndentStyle(String value, int indentStyle) instead
-	 * @param options the given options
-	 * @param key the given key
-	 * @param indentStyle the given indent style
-	 */
-	public static void setIndentStyle(Map options, String key, int indentStyle) {
-		Object option = options.get(key);
-		if (option != null) {
-			try {
-				int existingValue = Integer.parseInt((String) options.get(key));
-				// clear existing indent bits
-				existingValue &= ~(Alignment.M_INDENT_BY_ONE | Alignment.M_INDENT_ON_COLUMN);
-				switch(indentStyle) {
-					case INDENT_BY_ONE :
-						existingValue |= Alignment.M_INDENT_BY_ONE;
-						break;
-					case INDENT_ON_COLUMN :
-						existingValue |= Alignment.M_INDENT_ON_COLUMN;
-				}
-				options.put(key, String.valueOf(existingValue));
-			} catch (NumberFormatException e) {
-				// nothing to do
-			}
-		}
-	}
-	
-	/**
 	 * <p>Set the indentation style of the given alignment value and return the new value.
 	 * The given value should be created using the <code>createAlignmentValue(boolean, int, int)</code>
 	 * API.
@@ -2476,29 +2360,6 @@
 		}
 	}
 	/**
-	 * @deprecated Use setForceWrapping(String value, boolean force) instead
-	 * @param options the given options
-	 * @param key the given key
-	 * @param forceSplit the given force style
-	 */
-	public static void setForceWrapping(Map options, String key, boolean forceSplit) {
-		Object option = options.get(key);
-		if (option != null) {
-			try {
-				int existingValue = Integer.parseInt((String) option);
-				// clear existing force bit
-				existingValue &= ~Alignment.M_FORCE;
-				if (forceSplit) {
-					existingValue |= Alignment.M_FORCE;
-				}
-				options.put(key, String.valueOf(existingValue));
-			} catch (NumberFormatException e) {
-				// nothing to do
-			}
-		}
-	}
-
-	/**
 	 * <p>Set the force value of the given alignment value and return the new value.
 	 * The given alignment value should be created using the <code>createAlignmentValue(boolean, int, int)</code>
 	 * API.
@@ -2527,44 +2388,6 @@
 			throw WRONG_ARGUMENT;
 		}		
 	}
-	
-	/**
-	 * @deprecated use setWrappingStyle(String value, int wrappingStyle) instead
-	 * @param options the given options
-	 * @param key the given key
-	 * @param splitStyle the given split style
-	 */
-	public static void setWrappingStyle(Map options, String key, int splitStyle) {
-		Object option = options.get(key);
-		if (option != null) {
-			try {
-				int existingValue = Integer.parseInt((String) option);
-				// clear existing split bits
-				existingValue &= ~(Alignment.SPLIT_MASK);
-				switch(splitStyle) {
-					case WRAP_COMPACT :
-						existingValue |= Alignment.M_COMPACT_SPLIT;
-						break;
-					case WRAP_COMPACT_FIRST_BREAK :
-						existingValue |= Alignment.M_COMPACT_FIRST_BREAK_SPLIT;
-						break;
-					case WRAP_NEXT_PER_LINE :
-						existingValue |= Alignment.M_NEXT_PER_LINE_SPLIT;
-						break;
-					case WRAP_NEXT_SHIFTED :
-						existingValue |= Alignment.M_NEXT_SHIFTED_SPLIT;
-						break;
-					case WRAP_ONE_PER_LINE :
-						existingValue |= Alignment.M_ONE_PER_LINE_SPLIT;
-						break;
-				}
-				options.put(key, String.valueOf(existingValue));
-			} catch (NumberFormatException e) {
-				// nothing to do
-			}
-		}
-	}	
-	
 	/**
 	 * <p>Set the wrapping style of the given alignment value and return the new value.
 	 * The given value should be created using the <code>createAlignmentValue(boolean, int, int)</code>
@@ -2626,7 +2449,16 @@
 			throw WRONG_ARGUMENT;
 		}
 	}
-	
+	/**
+	 * Create a new alignment value according to the given values. This must be used to set up
+	 * the alignment options.
+	 * 
+	 * @param forceSplit the given force value
+	 * @param wrapStyle the given wrapping style
+	 * @param indentStyle the given indent style
+	 * 
+	 * @return the new alignement value
+	 */
 	public static String createAlignmentValue(boolean forceSplit, int wrapStyle, int indentStyle) {
 		int alignmentValue = 0; 
 		switch(wrapStyle) {
@@ -2658,413 +2490,4 @@
 		}
 		return String.valueOf(alignmentValue);
 	}
-	/*
-	 * All deprecated fields
-	 */
-	/**
-	 * @deprecated Use FORMATTER_ALIGNMENT_FOR_PARAMETERS_IN_METHOD_DECLARATION instead
-	 */
-	public static final String FORMATTER_METHOD_DECLARATION_ARGUMENTS_ALIGNMENT = JavaCore.PLUGIN_ID + ".formatter.method_declaration_arguments_alignment";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_METHOD_INVOCATION instead
-	 */
-	public static final String FORMATTER_MESSAGE_SEND_ARGUMENTS_ALIGNMENT = JavaCore.PLUGIN_ID + ".formatter.message_send_arguments_alignment";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_ALIGNMENT_FOR_SELECTOR_IN_METHOD_INVOCATION instead
-	 */
-	public static final String FORMATTER_MESSAGE_SEND_SELECTOR_ALIGNMENT = JavaCore.PLUGIN_ID + ".formatter.message_send_selector_alignment";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_QUALIFIED_ALLOCATION_EXPRESSION instead
-	 */
-	public static final String FORMATTER_QUALIFIED_ALLOCATION_EXPRESSION_ARGUMENTS_ALIGNMENT = JavaCore.PLUGIN_ID + ".formatter.qualified_allocation_expression_arguments_alignment";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_ALIGNMENT_FOR_SUPERCLASS_IN_TYPE_DECLARATION instead
-	 */
-	public static final String FORMATTER_TYPE_DECLARATION_SUPERCLASS_ALIGNMENT = JavaCore.PLUGIN_ID + ".formatter.type_declaration_superclass_alignment";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_ALIGNMENT_FOR_SUPERINTERFACES_IN_TYPE_DECLARATION instead
-	 */
-	public static final String FORMATTER_TYPE_DECLARATION_SUPERINTERFACES_ALIGNMENT = JavaCore.PLUGIN_ID + ".formatter.type_declaration_superinterfaces_alignment";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_ALIGNMENT_FOR_THROWS_CLAUSE_IN_METHOD_DECLARATION instead
-	 */
-	public static final String FORMATTER_METHOD_THROWS_CLAUSE_ALIGNMENT = JavaCore.PLUGIN_ID + ".formatter.method_throws_clause_alignment";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_ALIGNMENT_FOR_CONDITIONAL_EXPRESSION instead
-	 */
-	public static final String FORMATTER_CONDITIONAL_EXPRESSION_ALIGNMENT = JavaCore.PLUGIN_ID + ".formatter.conditional_expression_alignment";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_ALLOCATION_EXPRESSION instead
-	 */
-	public static final String FORMATTER_ALLOCATION_EXPRESSION_ARGUMENTS_ALIGNMENT  = JavaCore.PLUGIN_ID + ".formatter.allocation_expression_arguments_alignment";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_ALIGNMENT_FOR_COMPACT_IF instead
-	 */
-	public static final String FORMATTER_COMPACT_IF_ALIGNMENT = JavaCore.PLUGIN_ID + ".formatter.compact_if_alignment";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_ALIGNMENT_FOR_EXPRESSIONS_IN_ARRAY_INITIALIZER instead
-	 */
-	public static final String FORMATTER_ARRAY_INITIALIZER_EXPRESSIONS_ALIGNMENT = JavaCore.PLUGIN_ID + ".formatter.array_initializer_expressions_alignment";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_ALIGNMENT_FOR_BINARY_EXPRESSION instead
-	 */
-	public static final String FORMATTER_BINARY_EXPRESSION_ALIGNMENT = JavaCore.PLUGIN_ID + ".formatter.binary_expression_alignment";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_EXPLICIT_CONSTRUCTOR_CALL instead
-	 */
-	public static final String FORMATTER_EXPLICIT_CONSTRUCTOR_ARGUMENTS_ALIGNMENT = JavaCore.PLUGIN_ID + ".formatter.explicit_constructor_arguments_alignment";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_BRACE_POSITION_FOR_ANONYMOUS_TYPE_DECLARATION instead
-	 */
-	public static final String FORMATTER_ANONYMOUS_TYPE_DECLARATION_BRACE_POSITION = JavaCore.PLUGIN_ID + ".formatter.anonymous_type_declaration_brace_position";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_BRACE_POSITION_FOR_ARRAY_INITIALIZER instead
-	 */
-	public static final String FORMATTER_ARRAY_INITIALIZER_BRACE_POSITION = JavaCore.PLUGIN_ID + ".formatter.array_initializer_brace_position";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_BRACE_POSITION_FOR_BLOCK instead
-	 */
-	public static final String FORMATTER_BLOCK_BRACE_POSITION = JavaCore.PLUGIN_ID + ".formatter.block_brace_position";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_BRACE_POSITION_FOR_METHOD_DECLARATION instead
-	 */
-	public static final String FORMATTER_METHOD_DECLARATION_BRACE_POSITION = JavaCore.PLUGIN_ID + ".formatter.method_declaration_brace_position";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_BRACE_POSITION_FOR_TYPE_DECLARATION instead
-	 */
-	public static final String FORMATTER_TYPE_DECLARATION_BRACE_POSITION = JavaCore.PLUGIN_ID + ".formatter.type_declaration_brace_position";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_BRACE_POSITION_FOR_SWITCH instead
-	 */
-	public static final String FORMATTER_SWITCH_BRACE_POSITION = JavaCore.PLUGIN_ID + ".formatter.switch_brace_position";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_CONSTRUCTOR_DECLARATION_PARAMETERS insted
-	 */
-	public static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_CONSTRUCTOR_ARGUMENTS = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_comma_in_constructor_arguments";	//$NON-NLS-1$
-	/**
-	 * @deprecated use FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_METHOD_INVOCATION_ARGUMENTS instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_MESSAGESEND_ARGUMENTS = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_comma_in_messagesend_arguments";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_PARENTHESIZED_EXPRESSION instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_AFTER_OPEN_PAREN_IN_PARENTHESIZED_EXPRESSION = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_open_paren_in_parenthesized_expression"; //$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_METHOD_INVOCATION instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_MESSAGE_SEND = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_opening_paren_in_message_send"; //$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_METHOD_INVOCATION instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_MESSAGE_SEND = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_closing_paren_in_message_send"; //$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_CONSTRUCTOR_DECLARATION_PARAMETERS instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_CONSTRUCTOR_ARGUMENTS = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_comma_in_constructor_arguments";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_METHOD_INVOCATION_ARGUMENTS instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_MESSAGESEND_ARGUMENTS = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_comma_in_messagesend_arguments";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_METHOD_INVOCATION instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_BEFORE_MESSAGE_SEND = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_message_send";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_METHOD_DECLARATION instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_closing_paren";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_METHOD_DECLARATION instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_BEFORE_FIRST_ARGUMENT = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_first_argument";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_PARENS_IN_METHOD_DECLARATION instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_ARGUMENTS = JavaCore.PLUGIN_ID + ".formatter.insert_space_between_empty_arguments";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_METHOD_INVOCATION and FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_METHOD_INVOCATION instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_WITHIN_MESSAGE_SEND = JavaCore.PLUGIN_ID + ".formatter.insert_space_within_message_send";	//$NON-NLS-1$
-	/**
-	 * @deprecated use FORMATTER_INSERT_SPACE_AFTER_CLOSING_BRACE_IN_BLOCK instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_AFTER_BLOCK_CLOSE_BRACE = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_block_close_brace";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_ANONYMOUS_TYPE_DECLARATION instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_BEFORE_ANONYMOUS_TYPE_OPEN_BRACE = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_anonymous_type_open_brace"; 	//$NON-NLS-1$
-	/**
-	 * @deprecated use FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_BLOCK instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_BEFORE_BLOCK_OPEN_BRACE = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_block_open_brace";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_CATCH instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_BEFORE_CATCH_EXPRESSION = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_catch_expression";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_CONSTRUCTOR_DECLARATION instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_BEFORE_CONSTRUCTOR_DECLARATION_OPEN_PAREN = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_constructor_declaration_open_paren";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_AFTER_OPENING_BRACE_IN_ARRAY_INITIALIZER instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_BEFORE_FIRST_INITIALIZER = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_first_initializer";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_FOR instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_BEFORE_FOR_PAREN = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_for_paren";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_IF instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_BEFORE_IF_CONDITION = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_if_condition";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_METHOD_DECLARATION instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_BEFORE_METHOD_DECLARATION_OPEN_PAREN = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_method_declaration_open_paren";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_METHOD_DECLARATION instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_BEFORE_METHOD_OPEN_BRACE = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_method_open_brace";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_PARENTHESIZED_EXPRESSION instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_BEFORE_OPEN_PAREN_IN_PARENTHESIZED_EXPRESSION = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_open_paren_in_parenthesized_expression"; //$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_SWITCH instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_BEFORE_SWITCH_CONDITION = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_switch_condition";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_SWITCH instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_BEFORE_SWITCH_OPEN_BRACE = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_switch_open_brace";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_SYNCHRONIZED instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_BEFORE_SYNCHRONIZED_CONDITION = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_synchronized_condition";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_TYPE_DECLARATION instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_BEFORE_TYPE_OPEN_BRACE = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_type_open_brace";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_BEFORE_OPENING_PAREN_IN_WHILE instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_BEFORE_WHILE_CONDITION = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_while_condition";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_AFTER_OPENING_BRACKET_IN_ARRAY_REFERENCE and FORMATTER_INSERT_SPACE_BEFORE_CLOSING_BRACKET_IN_ARRAY_REFERENCE instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_BETWEEN_BRACKETS_IN_ARRAY_REFERENCE = JavaCore.PLUGIN_ID + ".formatter.insert_space_between_brackets_in_array_reference";//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_BRACES_IN_ARRAY_INITIALIZER instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_ARRAY_INITIALIZER = JavaCore.PLUGIN_ID + ".formatter.insert_space_between_empty_array_initializer";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_PARENS_IN_METHOD_INVOCATION
-	 */
-	public static final String FORMATTER_INSERT_SPACE_BETWEEN_EMPTY_MESSAGESEND_ARGUMENTS = JavaCore.PLUGIN_ID + ".formatter.insert_space_between_empty_messagesend_arguments";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_CATCH and FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_CATCH instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_IN_CATCH_EXPRESSION = JavaCore.PLUGIN_ID + ".formatter.insert_space_in_catch_expression";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_FOR and FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_FOR instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_IN_FOR_PARENS = JavaCore.PLUGIN_ID + ".formatter.insert_space_in_for_parens";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_IF and FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_IF instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_IN_IF_CONDITION = JavaCore.PLUGIN_ID + ".formatter.insert_space_in_if_condition";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_SWITCH and FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_SWITCH instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_IN_SWITCH_CONDITION = JavaCore.PLUGIN_ID + ".formatter.insert_space_in_switch_condition";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_SYNCHRONIZED and FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_SYNCHRONIZED instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_IN_SYNCHRONIZED_CONDITION = JavaCore.PLUGIN_ID + ".formatter.insert_space_in_synchronized_condition";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_AFTER_OPENING_PAREN_IN_WHILE and FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_WHILE instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_IN_WHILE_CONDITION = JavaCore.PLUGIN_ID + ".formatter.insert_space_in_while_condition";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACKET_IN_ARRAY_REFERENCE instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_BEFORE_BRACKET_IN_ARRAY_REFERENCE = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_bracket_in_array_reference";//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACKET_IN_ARRAY_TYPE_REFERENCE instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_BEFORE_BRACKET_IN_ARRAY_TYPE_REFERENCE = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_bracket_in_array_type_reference";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_BEFORE_ASSIGNMENT_OPERATOR instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_BEFORE_ASSIGNMENT_OPERATORS = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_assignment_operators";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_AFTER_ASSIGNMENT_OPERATOR instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_AFTER_ASSIGNMENT_OPERATORS = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_assignment_operators"; //$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_KEEP_GUARDIAN_CLAUSE_ON_ONE_LINE instead
-	 */
-	public static final String FORMATTER_FORMAT_GUARDIAN_CLAUSE_ON_ONE_LINE = JavaCore.PLUGIN_ID + ".formatter.format_guardian_clause_on_one_line";	//$NON-NLS-1$
-
-	
-	/**
-	 * @deprecated Use FORMATTER_CONTINUATION_INDENTATION_FOR_ARRAY_INITIALIZER instead
-	 */
-	public static final String FORMATTER_ARRAY_INITIALIZER_CONTINUATION_INDENTATION = JavaCore.PLUGIN_ID + ".formatter.array_initializer_continuation_indentation";	//$NON-NLS-1$
-	
-	/**
-	 * @deprecated Use FORMATTER_ALIGN_TYPE_MEMBERS_ON_COLUMNS instead
-	 */
-	public static final String FORMATTER_TYPE_MEMBER_ALIGNMENT = JavaCore.PLUGIN_ID + ".formatter.type_member_alignment";	 //$NON-NLS-1$
-	/** 
-	 * <table BORDER COLS=4 WIDTH="100%" >
-	 * <tr><td>#fragment1A</td>            <td>#fragment2A</td>       <td>#fragment3A</td>  <td>#very-long-fragment4A</td></tr>
-	 * <tr><td>#fragment1B</td>            <td>#long-fragment2B</td>  <td>#fragment3B</td>  <td>#fragment4B</td></tr>
-	 * <tr><td>#very-long-fragment1C</td>  <td>#fragment2C</td>       <td>#fragment3C</td>  <td>#fragment4C</td></tr>
-	 * </table>
-	 * @deprecated Removed
-	 */
-	public static final String FORMATTER_MULTICOLUMN = "256"; //$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_METHOD_DECLARATION_THROWS instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_METHOD_THROWS = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_comma_in_method_throws"; //$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_METHOD_DECLARATION_THROWS instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_METHOD_THROWS = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_comma_in_method_throws";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_METHOD_DECLARATION_PARAMETERS instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_METHOD_ARGUMENTS = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_comma_in_method_arguments";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_METHOD_DECLARATION_PARAMETERS instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_METHOD_ARGUMENTS = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_comma_in_method_arguments";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_CONSTRUCTOR_DECLARATION instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_BEFORE_CLOSING_PAREN_IN_CONSTRUCTOR = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_closing_paren_in_constructor";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_CONSTRUCTOR_DECLARATION instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_BEFORE_OPENING_BRACE_IN_CONSTRUCTOR = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_opening_brace_in_constructor";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_EXPLICIT_CONSTRUCTOR_CALL_ARGUMENTS instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_EXPLICITCONSTRUCTORCALL_ARGUMENTS = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_comma_in_explicitconstructorcall_arguments"; //$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_EXPLICIT_CONSTRUCTOR_CALL_ARGUMENTS instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_EXPLICITCONSTRUCTORCALL_ARGUMENTS = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_comma_in_explicitconstructorcall_arguments";	//$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_CONSTRUCTOR_DECLARATION_THROWS instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_AFTER_COMMA_IN_CONSTRUCTOR_THROWS = JavaCore.PLUGIN_ID + ".formatter.insert_space_after_comma_in_constructor_throws"; //$NON-NLS-1$
-	/**
-	 * @deprecated Use FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_CONSTRUCTOR_DECLARATION_THROWS instead
-	 */
-	public static final String FORMATTER_INSERT_SPACE_BEFORE_COMMA_IN_CONSTRUCTOR_THROWS = JavaCore.PLUGIN_ID + ".formatter.insert_space_before_comma_in_constructor_throws";	//$NON-NLS-1$
-	/**
-	 * if bit set, then alignment will be non-optional (default is optional)
-	 * @deprecated Use the API method to set alignments
-	 */
-	public static final String FORMATTER_ALIGNMENT_FORCE = "1";//$NON-NLS-1$
-
-	/** foobar(<ul>
-	 * <li>    #fragment1, #fragment2,  </li>
-	 * <li>     #fragment5, #fragment4, </li>
-	 * </ul>
-	 * @deprecated Use the API method to set alignments
-	 */
-	public static final String FORMATTER_COMPACT_FIRST_BREAK_SPLIT = "32";//$NON-NLS-1$
-	/** foobar(#fragment1, #fragment2, <ul>
-	 *  <li>    #fragment3, #fragment4 </li>
-	 * </ul>
-	 * @deprecated Use the API method to set alignments
-	 */
-	public static final String FORMATTER_COMPACT_SPLIT = "16";//$NON-NLS-1$
-	/**
-	 * if bit set, broken fragments will be indented one level below current (not using continuation indentation)
-	 * @deprecated Use the API method to set alignments
-	 */
-	public static final String FORMATTER_INDENT_BY_ONE = "4";//$NON-NLS-1$
-	/**
-	 * if bit set, broken fragments will be aligned on current location column (default is to break at current indentation level)
-	 * @deprecated Use the API method to set alignments
-	 */
-	public static final String FORMATTER_INDENT_ON_COLUMN = "2";//$NON-NLS-1$
-	/** foobar(#fragment1, <ul>
-	 * <li>      #fragment2,  </li>
-	 * <li>      #fragment3 </li>
-	 * <li>      #fragment4,  </li>
-	 * </ul>
-	 * @deprecated Use the API method to set alignments
-	 */
-	public static final String FORMATTER_NEXT_PER_LINE_SPLIT = "80"; //$NON-NLS-1$
-	/** 
-	 * foobar(<ul>
-	 * <li>     #fragment1,  </li>
-	 * <li>        #fragment2,  </li>
-	 * <li>        #fragment3 </li>
-	 * <li>        #fragment4,  </li>
-	 * </ul>
-	 * @deprecated Use the API method to set alignments
-	 */ 
-	public static final String FORMATTER_NEXT_SHIFTED_SPLIT = "64";//$NON-NLS-1$
-
-	/**
-	 * Use to disable line wrapping/splitting
-	 * @deprecated Use the API method to set alignments
-	 */
-	public static final String FORMATTER_NO_ALIGNMENT = "0";//$NON-NLS-1$
-
-	/** foobar(<ul>
-	 * <li>     #fragment1,  </li>
-	 * <li>     #fragment2,  </li>
-	 * <li>     #fragment3 </li>
-	 * <li>     #fragment4,  </li>
-	 * </ul>
-	 * @deprecated Use the API method to set alignments
-	 */
-	public static final String FORMATTER_ONE_PER_LINE_SPLIT = "48";//$NON-NLS-1$
-	/**
-	 * <pre>
-	 * FORMATTER / Option to indent statements inside a block
-	 *     - option id:         "org.eclipse.jdt.core.formatter.indent_block_statements"
-	 *     - possible values:   { TRUE, FALSE }
-	 *     - default:           TRUE
-	 * </pre>
-	 * @see #TRUE
-	 * @see #FALSE
-	 * @deprecated Use FORMATTER_INDENT_STATEMENTS_COMPARE_TO_BODY and FORMATTER_INDENT_STATEMENTS_COMPARE_TO_BLOCK instead
-	 * @since 3.0
-	 */
-	public static final String FORMATTER_INDENT_BLOCK_STATEMENTS = JavaCore.PLUGIN_ID + ".formatter.indent_block_statements"; //$NON-NLS-1$
-	/**
-	 * <pre>
-	 * FORMATTER / Option to specify whether or not unnecessary semicolon should be removed
-	 *     - option id:         "org.eclipse.jdt.core.formatter.remove_unnecessary_semicolon"
-	 *     - possible values:   { TRUE, FALSE }
-	 *     - default:           FALSE
-	 * </pre>
-	 * @see #TRUE
-	 * @see #FALSE
-	 * @deprecated Will be removed.
-	 * @since 3.0
-	 */
-	public static final String FORMATTER_REMOVE_UNNECESSARY_SEMICOLON = JavaCore.PLUGIN_ID + ".formatter.remove_unnecessary_semicolon";	//$NON-NLS-1$
-	/**
-	 * <pre>
-	 * FORMATTER / Option to insert a new line in control statements
-	 *     - option id:         "org.eclipse.jdt.core.formatter.insert_new_line_in_control_statements"
-	 *     - possible values:   { INSERT, DO_NOT_INSERT }
-	 *     - default:           DO_NOT_INSERT
-	 * </pre>
-	 * @see JavaCore#INSERT
-	 * @see JavaCore#DO_NOT_INSERT
-	 * @since 3.0
-	 * @deprecated Will be removed before M9 please use the specific FORMATTER_INSERT_NEW_LINE_IN_XX_STATEMENT where XX represents the specific statement
-	 */
-	public static final String FORMATTER_INSERT_NEW_LINE_IN_CONTROL_STATEMENTS = JavaCore.PLUGIN_ID + ".formatter.insert_new_line_in_control_statements";	//$NON-NLS-1$
 }
diff --git a/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java b/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java
index d154390..bd4668a 100644
--- a/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java
+++ b/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatter.java
@@ -36,7 +36,7 @@
 	private CodeSnippetParsingUtil codeSnippetParsingUtil;
 	
 	public DefaultCodeFormatter() {
-		this(new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getDefaultSettings()), null);
+		this(new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getJavaConventionsSettings()), null);
 	}
 	
 	public DefaultCodeFormatter(DefaultCodeFormatterOptions preferences) {
@@ -49,7 +49,7 @@
 			this.preferences = new DefaultCodeFormatterOptions(options);
 		} else {
 			this.options = JavaCore.getOptions();
-			this.preferences = new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getDefaultSettings());
+			this.preferences = new DefaultCodeFormatterOptions(DefaultCodeFormatterConstants.getJavaConventionsSettings());
 		}
 		this.defaultCompilerOptions = getDefaultCompilerOptions();
 		if (defaultCodeFormatterOptions != null) {
diff --git a/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatterOptions.java b/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatterOptions.java
index fd984b6..5943709 100644
--- a/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatterOptions.java
+++ b/formatter/org/eclipse/jdt/internal/formatter/DefaultCodeFormatterOptions.java
@@ -1523,7 +1523,7 @@
 		this.blank_lines_after_imports = 1;
 		this.blank_lines_after_package = 1;
 		this.blank_lines_before_field = 1;
-		this.blank_lines_before_first_class_body_declaration = 1;
+		this.blank_lines_before_first_class_body_declaration = 0;
 		this.blank_lines_before_imports = 1;
 		this.blank_lines_before_member_type = 1;
 		this.blank_lines_before_method = 1;
@@ -1654,10 +1654,10 @@
 		this.insert_space_between_empty_parens_in_method_declaration = false;
 		this.insert_space_between_empty_parens_in_method_invocation = false;
 		this.compact_else_if = true;
-		this.keep_guardian_clause_on_one_line = true;
+		this.keep_guardian_clause_on_one_line = false;
 		this.keep_else_statement_on_same_line = false;
 		this.keep_empty_array_initializer_on_one_line = false;
-		this.keep_simple_if_on_one_line = true;
+		this.keep_simple_if_on_one_line = false;
 		this.keep_then_statement_on_same_line = false;
 		this.number_of_empty_lines_to_preserve = 1;
 		this.put_empty_statement_on_new_line = true;
diff --git a/formatter/org/eclipse/jdt/internal/formatter/old/CodeFormatter.java b/formatter/org/eclipse/jdt/internal/formatter/old/CodeFormatter.java
index aa9f8c3..7b7be0c 100644
--- a/formatter/org/eclipse/jdt/internal/formatter/old/CodeFormatter.java
+++ b/formatter/org/eclipse/jdt/internal/formatter/old/CodeFormatter.java
@@ -40,7 +40,7 @@
 	
 	public String format(String string, int indentLevel, int[] positions, String lineSeparator) {
 		// initialize the new formatter with old options
-		Map newOptions = DefaultCodeFormatterConstants.getDefaultSettings();
+		Map newOptions = DefaultCodeFormatterConstants.getEclipse21Settings();
 
 		Object formatterNewLineOpeningBrace = this.options.get(JavaCore.FORMATTER_NEWLINE_OPENING_BRACE);
 		if (formatterNewLineOpeningBrace != null) {
@@ -63,9 +63,15 @@
 		Object formatterNewLineControl = this.options.get(JavaCore.FORMATTER_NEWLINE_CONTROL);
 		if (formatterNewLineControl != null) {
 			if (JavaCore.INSERT.equals(formatterNewLineControl)) {
-				newOptions.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_CONTROL_STATEMENTS, JavaCore.INSERT);
+				newOptions.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_CATCH_IN_TRY_STATEMENT, JavaCore.INSERT);
+				newOptions.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_ELSE_IN_IF_STATEMENT, JavaCore.INSERT);
+				newOptions.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_FINALLY_IN_TRY_STATEMENT, JavaCore.INSERT);
+				newOptions.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_WHILE_IN_DO_STATEMENT, JavaCore.INSERT);
 			} else {
-				newOptions.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_IN_CONTROL_STATEMENTS, JavaCore.DO_NOT_INSERT);
+				newOptions.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_CATCH_IN_TRY_STATEMENT, JavaCore.DO_NOT_INSERT);
+				newOptions.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_ELSE_IN_IF_STATEMENT, JavaCore.DO_NOT_INSERT);
+				newOptions.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_FINALLY_IN_TRY_STATEMENT, JavaCore.DO_NOT_INSERT);
+				newOptions.put(DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_BEFORE_WHILE_IN_DO_STATEMENT, JavaCore.DO_NOT_INSERT);
 			}
 		}
 		Object formatterClearBlankLines = this.options.get(JavaCore.FORMATTER_CLEAR_BLANK_LINES);
diff --git a/model/org/eclipse/jdt/core/IType.java b/model/org/eclipse/jdt/core/IType.java
index d02e20e..2b90178 100644
--- a/model/org/eclipse/jdt/core/IType.java
+++ b/model/org/eclipse/jdt/core/IType.java
@@ -862,18 +862,29 @@
 	
 	/**
 	 * Resolves the given type name within the context of this type (depending on the type hierarchy 
-	 * and its imports). Multiple answers might be found in case there are ambiguous matches.
-	 *
+	 * and its imports). 
+	 * <p>
+	 * Multiple answers might be found in case there are ambiguous matches.
+	 * </p>
+	 * <p>
 	 * Each matching type name is decomposed as an array of two strings, the first denoting the package
-	 * name (dot-separated) and the second being the type name.
+	 * name (dot-separated) and the second being the type name. The package name is empty if it is the
+	 * default package. The type name is the type qualified name using a '.' enclosing type separator.
+	 * </p>
+	 * <p>
 	 * Returns <code>null</code> if unable to find any matching type.
-	 *
+	 * </p>
+	 *<p>
 	 * For example, resolution of <code>"Object"</code> would typically return
-	 * <code>{{"java.lang", "Object"}}</code>.
+	 * <code>{{"java.lang", "Object"}}</code>. Another resolution that returns
+	 * <code>{{"", "X.Inner"}}</code> represents the inner type Inner defined in type X in the 
+	 * default package.
+	 * </p>
 	 * 
 	 * @param typeName the given type name
 	 * @exception JavaModelException if code resolve could not be performed. 
 	 * @return the resolved type names or <code>null</code> if unable to find any matching type
+	 * @see #getTypeQualifiedName(char)
 	 */
 	String[][] resolveType(String typeName) throws JavaModelException;
 
@@ -891,18 +902,24 @@
 	 * </p>
 	 * <p>
 	 * Each matching type name is decomposed as an array of two strings, the first denoting the package
-	 * name (dot-separated) and the second being the type name.
+	 * name (dot-separated) and the second being the type name. The package name is empty if it is the
+	 * default package. The type name is the type qualified name using a '.' enclosing type separator.
+	 * </p>
+	 * <p>
 	 * Returns <code>null</code> if unable to find any matching type.
 	 *</p>
 	 *<p>
 	 * For example, resolution of <code>"Object"</code> would typically return
-	 * <code>{{"java.lang", "Object"}}</code>.
+	 * <code>{{"java.lang", "Object"}}</code>. Another resolution that returns
+	 * <code>{{"", "X.Inner"}}</code> represents the inner type Inner defined in type X in the 
+	 * default package.
 	 * </p>
 	 * 
 	 * @param typeName the given type name
 	 * @param owner the owner of working copies that take precedence over their original compilation units
 	 * @exception JavaModelException if code resolve could not be performed. 
 	 * @return the resolved type names or <code>null</code> if unable to find any matching type
+	 * @see #getTypeQualifiedName(char)
 	 * @since 3.0
 	 */
 	String[][] resolveType(String typeName, WorkingCopyOwner owner) throws JavaModelException;
diff --git a/model/org/eclipse/jdt/core/JavaCore.java b/model/org/eclipse/jdt/core/JavaCore.java
index 45e03f7..7af34d9 100644
--- a/model/org/eclipse/jdt/core/JavaCore.java
+++ b/model/org/eclipse/jdt/core/JavaCore.java
@@ -2459,7 +2459,7 @@
 		optionNames.add(CORE_ENCODING);
 		
 		// Formatter settings
-		Map codeFormatterOptionsMap = DefaultCodeFormatterConstants.getDefaultSettings(); // code formatter defaults
+		Map codeFormatterOptionsMap = DefaultCodeFormatterConstants.getJavaConventionsSettings(); // code formatter defaults
 		for (Iterator iter = codeFormatterOptionsMap.entrySet().iterator(); iter.hasNext();) {
 			Map.Entry entry = (Map.Entry) iter.next();
 			String optionName = (String) entry.getKey();
diff --git a/model/org/eclipse/jdt/internal/compiler/SourceElementParser.java b/model/org/eclipse/jdt/internal/compiler/SourceElementParser.java
index c2d9d8e..c72d51c 100644
--- a/model/org/eclipse/jdt/internal/compiler/SourceElementParser.java
+++ b/model/org/eclipse/jdt/internal/compiler/SourceElementParser.java
@@ -265,17 +265,19 @@
 	// the scanner is located after the comma or the semi-colon.
 	// we want to include the comma or the semi-colon
 	super.consumeExitVariableWithInitialization();
-	if (isLocalDeclaration() || ((currentToken != TokenNameCOMMA) && (currentToken != TokenNameSEMICOLON)))
-		return;
-	((SourceFieldDeclaration) astStack[astPtr]).fieldEndPosition = scanner.currentPosition - 1;
+	if ((currentToken == TokenNameCOMMA || currentToken == TokenNameSEMICOLON)
+			&& astStack[astPtr] instanceof SourceFieldDeclaration) {
+		((SourceFieldDeclaration) astStack[astPtr]).fieldEndPosition = scanner.currentPosition - 1;
+	}
 }
 protected void consumeExitVariableWithoutInitialization() {
 	// ExitVariableWithoutInitialization ::= $empty
 	// do nothing by default
 	super.consumeExitVariableWithoutInitialization();
-	if (isLocalDeclaration() || ((currentToken != TokenNameCOMMA) && (currentToken != TokenNameSEMICOLON)))
-		return;
-	((SourceFieldDeclaration) astStack[astPtr]).fieldEndPosition = scanner.currentPosition - 1;
+	if ((currentToken == TokenNameCOMMA || currentToken == TokenNameSEMICOLON)
+			&& astStack[astPtr] instanceof SourceFieldDeclaration) {
+		((SourceFieldDeclaration) astStack[astPtr]).fieldEndPosition = scanner.currentPosition - 1;
+	}
 }
 /*
  *
@@ -619,20 +621,6 @@
 	return ref;
 }
 /*
- *
- * INTERNAL USE-ONLY
- */
-private boolean isLocalDeclaration() {
-	int nestedDepth = nestedType;
-	while (nestedDepth >= 0) {
-		if (nestedMethod[nestedDepth] != 0) {
-			return true;
-		}
-		nestedDepth--;
-	}
-	return false;
-}
-/*
  * Update the bodyStart of the corresponding parse node
  */
 public void notifySourceElementRequestor(CompilationUnitDeclaration parsedUnit) {
@@ -1180,7 +1168,7 @@
 		CompilationResult compilationUnitResult = new CompilationResult(unit, 0, 0, this.options.maxProblemsPerUnit);
 		CompilationUnitDeclaration parsedUnit = parse(unit, compilationUnitResult, start, end);
 		if (scanner.recordLineSeparator) {
-			requestor.acceptLineSeparatorPositions(scanner.getLineEnds());
+			requestor.acceptLineSeparatorPositions(compilationUnitResult.lineSeparatorPositions);
 		}
 		if (this.localDeclarationVisitor != null || fullParse){
 			diet = false;
@@ -1210,7 +1198,7 @@
 		CompilationResult compilationUnitResult = new CompilationResult(unit, 0, 0, this.options.maxProblemsPerUnit);
 		CompilationUnitDeclaration parsedUnit = parse(unit, compilationUnitResult);
 		if (scanner.recordLineSeparator) {
-			requestor.acceptLineSeparatorPositions(scanner.getLineEnds());
+			requestor.acceptLineSeparatorPositions(compilationUnitResult.lineSeparatorPositions);
 		}
 		int initialStart = this.scanner.initialPosition;
 		int initialEnd = this.scanner.eofPosition;
@@ -1240,11 +1228,11 @@
 		unknownRefsCounter = 0;
 	}
 	
+	CompilationResult compilationUnitResult = 
+		new CompilationResult(sourceUnit, 0, 0, this.options.maxProblemsPerUnit); 
 	try {
 		diet = !needReferenceInfo;
 		reportReferenceInfo = needReferenceInfo;
-		CompilationResult compilationUnitResult = 
-			new CompilationResult(sourceUnit, 0, 0, this.options.maxProblemsPerUnit); 
 		CompilationUnitDeclaration unit = 
 			SourceTypeConverter.buildCompilationUnit(
 				new ISourceType[]{type}, 
@@ -1280,7 +1268,7 @@
 		// ignore this exception
 	} finally {
 		if (scanner.recordLineSeparator) {
-			requestor.acceptLineSeparatorPositions(scanner.getLineEnds());
+			requestor.acceptLineSeparatorPositions(compilationUnitResult.lineSeparatorPositions);
 		}
 		diet = old;
 	}
diff --git a/model/org/eclipse/jdt/internal/compiler/SourceElementRequestorAdapter.java b/model/org/eclipse/jdt/internal/compiler/SourceElementRequestorAdapter.java
index 71985da..9693f0d 100644
--- a/model/org/eclipse/jdt/internal/compiler/SourceElementRequestorAdapter.java
+++ b/model/org/eclipse/jdt/internal/compiler/SourceElementRequestorAdapter.java
@@ -14,7 +14,7 @@
 
 public class SourceElementRequestorAdapter implements ISourceElementRequestor {
 
-	/*
+	/**
 	 * @see ISourceElementRequestor#acceptConstructorReference(char[], int, int)
 	 */
 	public void acceptConstructorReference(
@@ -24,14 +24,14 @@
 		// default implementation: do nothing
 	}
 
-	/*
+	/**
 	 * @see ISourceElementRequestor#acceptFieldReference(char[], int)
 	 */
 	public void acceptFieldReference(char[] fieldName, int sourcePosition) {
 		// default implementation: do nothing
 	}
 
-	/*
+	/**
 	 * @see ISourceElementRequestor#acceptImport(int, int, char[], boolean, int)
 	 */
 	public void acceptImport(
@@ -43,14 +43,14 @@
 		// default implementation: do nothing
 	}
 
-	/*
+	/**
 	 * @see ISourceElementRequestor#acceptLineSeparatorPositions(int[])
 	 */
 	public void acceptLineSeparatorPositions(int[] positions) {
 		// default implementation: do nothing
 	}
 
-	/*
+	/**
 	 * @see ISourceElementRequestor#acceptMethodReference(char[], int, int)
 	 */
 	public void acceptMethodReference(
@@ -60,7 +60,7 @@
 		// default implementation: do nothing
 	}
 
-	/*
+	/**
 	 * @see ISourceElementRequestor#acceptPackage(int, int, char[])
 	 */
 	public void acceptPackage(
@@ -70,14 +70,14 @@
 		// default implementation: do nothing
 	}
 
-	/*
+	/**
 	 * @see ISourceElementRequestor#acceptProblem(IProblem)
 	 */
 	public void acceptProblem(IProblem problem) {
 		// default implementation: do nothing
 	}
 
-	/*
+	/**
 	 * @see ISourceElementRequestor#acceptTypeReference(char[][], int, int)
 	 */
 	public void acceptTypeReference(
@@ -87,14 +87,14 @@
 		// default implementation: do nothing
 	}
 
-	/*
+	/**
 	 * @see ISourceElementRequestor#acceptTypeReference(char[], int)
 	 */
 	public void acceptTypeReference(char[] typeName, int sourcePosition) {
 		// default implementation: do nothing
 	}
 
-	/*
+	/**
 	 * @see ISourceElementRequestor#acceptUnknownReference(char[][], int, int)
 	 */
 	public void acceptUnknownReference(
@@ -104,14 +104,14 @@
 		// default implementation: do nothing
 	}
 
-	/*
+	/**
 	 * @see ISourceElementRequestor#acceptUnknownReference(char[], int)
 	 */
 	public void acceptUnknownReference(char[] name, int sourcePosition) {
 		// default implementation: do nothing
 	}
 
-	/*
+	/**
 	 * @see ISourceElementRequestor#enterClass(int, int, char[], int, int, char[], char[][])
 	 */
 	public void enterClass(
@@ -127,14 +127,14 @@
 		// default implementation: do nothing
 	}
 
-	/*
+	/**
 	 * @see ISourceElementRequestor#enterCompilationUnit()
 	 */
 	public void enterCompilationUnit() {
 		// default implementation: do nothing
 	}
 
-	/*
+	/**
 	 * @see ISourceElementRequestor#enterConstructor(int, int, char[], int, int, char[][], char[][], char[][])
 	 */
 	public void enterConstructor(
@@ -149,7 +149,7 @@
 		// default implementation: do nothing
 	}
 
-	/*
+	/**
 	 * @see ISourceElementRequestor#enterField(int, int, char[], char[], int, int)
 	 */
 	public void enterField(
@@ -162,14 +162,14 @@
 		// default implementation: do nothing
 	}
 
-	/*
+	/**
 	 * @see ISourceElementRequestor#enterInitializer(int, int)
 	 */
 	public void enterInitializer(int declarationStart, int modifiers) {
 		// default implementation: do nothing
 	}
 
-	/*
+	/**
 	 * @see ISourceElementRequestor#enterInterface(int, int, char[], int, int, char[][])
 	 */
 	public void enterInterface(
@@ -184,7 +184,7 @@
 		// default implementation: do nothing
 	}
 
-	/*
+	/**
 	 * @see ISourceElementRequestor#enterMethod(int, int, char[], char[], int, int, char[][], char[][], char[][])
 	 */
 	public void enterMethod(
@@ -200,54 +200,53 @@
 		// default implementation: do nothing
 	}
 
-	/*
+	/**
 	 * @see ISourceElementRequestor#exitClass(int)
 	 */
 	public void exitClass(int declarationEnd) {
 		// default implementation: do nothing
 	}
 
-	/*
+	/**
 	 * @see ISourceElementRequestor#exitCompilationUnit(int)
 	 */
 	public void exitCompilationUnit(int declarationEnd) {
 		// default implementation: do nothing
 	}
 
-	/*
+	/**
 	 * @see ISourceElementRequestor#exitConstructor(int)
 	 */
 	public void exitConstructor(int declarationEnd) {
 		// default implementation: do nothing
 	}
 
-	/*
+	/**
 	 * @see ISourceElementRequestor#exitField(int)
 	 */
 	public void exitField(int initializationStart, int declarationEnd, int declarationSourceEnd) {
 		// default implementation: do nothing
 	}
 
-	/*
+	/**
 	 * @see ISourceElementRequestor#exitInitializer(int)
 	 */
 	public void exitInitializer(int declarationEnd) {
 		// default implementation: do nothing
 	}
 
-	/*
+	/**
 	 * @see ISourceElementRequestor#exitInterface(int)
 	 */
 	public void exitInterface(int declarationEnd) {
 		// default implementation: do nothing
 	}
 
-	/*
+	/**
 	 * @see ISourceElementRequestor#exitMethod(int)
 	 */
 	public void exitMethod(int declarationEnd) {
 		// default implementation: do nothing
 	}
-
 }
 
diff --git a/model/org/eclipse/jdt/internal/compiler/parser/SourceTypeConverter.java b/model/org/eclipse/jdt/internal/compiler/parser/SourceTypeConverter.java
index 552739d..4ca80ed 100644
--- a/model/org/eclipse/jdt/internal/compiler/parser/SourceTypeConverter.java
+++ b/model/org/eclipse/jdt/internal/compiler/parser/SourceTypeConverter.java
@@ -96,13 +96,15 @@
 	 * at least contain one type.
 	 */
 	private CompilationUnitDeclaration convert(ISourceType[] sourceTypes, CompilationResult compilationResult) {
-		ISourceType sourceType = sourceTypes[0];
-		if (sourceType.getName() == null)
-			return null; // do a basic test that the sourceType is valid
-
 		this.unit = new CompilationUnitDeclaration(this.problemReporter, compilationResult, 0);
 		// not filled at this point
 
+		if (sourceTypes.length == 0) return this.unit;
+		ISourceType sourceType = sourceTypes[0];
+		if (sourceType.getName() == null)
+		    // TODO (jerome) investigate when this can happen : if this can happen, fix clients to protect themselves
+			return null; // do a basic test that the sourceType is valid
+
 		/* only positions available */
 		int start = sourceType.getNameSourceStart();
 		int end = sourceType.getNameSourceEnd();
diff --git a/model/org/eclipse/jdt/internal/core/CompilationUnit.java b/model/org/eclipse/jdt/internal/core/CompilationUnit.java
index 58d98ab..1e13c5e 100644
--- a/model/org/eclipse/jdt/internal/core/CompilationUnit.java
+++ b/model/org/eclipse/jdt/internal/core/CompilationUnit.java
@@ -149,7 +149,7 @@
 		
 		if (info instanceof ASTHolderCUInfo) {
 			int astLevel = ((ASTHolderCUInfo) info).astLevel;
-			org.eclipse.jdt.core.dom.CompilationUnit cu = AST.convertCompilationUnit(astLevel, unit, contents, options, pm);
+			org.eclipse.jdt.core.dom.CompilationUnit cu = AST.convertCompilationUnit(astLevel, unit, contents, options, computeProblems, pm);
 			((ASTHolderCUInfo) info).ast = cu;
 		}
 	} finally {
diff --git a/model/org/eclipse/jdt/internal/core/DeltaProcessor.java b/model/org/eclipse/jdt/internal/core/DeltaProcessor.java
index 90f8ff3..dcd976d 100644
--- a/model/org/eclipse/jdt/internal/core/DeltaProcessor.java
+++ b/model/org/eclipse/jdt/internal/core/DeltaProcessor.java
@@ -1195,7 +1195,9 @@
 				if (rootInfo != null && rootInfo.isRootOfProject(res.getFullPath())) {
 					return IJavaElement.PACKAGE_FRAGMENT_ROOT;
 				} 
-				return NON_JAVA_RESOURCE; // not yet in a package fragment root or root of another project
+				// not yet in a package fragment root or root of another project
+				// or package fragment to be included (see below)
+				// -> let it go through
 
 			case IJavaElement.PACKAGE_FRAGMENT_ROOT:
 			case IJavaElement.PACKAGE_FRAGMENT:
diff --git a/model/org/eclipse/jdt/internal/core/JarPackageFragment.java b/model/org/eclipse/jdt/internal/core/JarPackageFragment.java
index 4ccf2f8..207337e 100644
--- a/model/org/eclipse/jdt/internal/core/JarPackageFragment.java
+++ b/model/org/eclipse/jdt/internal/core/JarPackageFragment.java
@@ -39,11 +39,10 @@
  * Compute the children of this package fragment. Children of jar package fragments
  * can only be IClassFile (representing .class files).
  */
-protected boolean computeChildren(OpenableElementInfo info) {
-	JarPackageFragmentInfo jInfo= (JarPackageFragmentInfo)info;
-	if (jInfo.entryNames != null){
+protected boolean computeChildren(OpenableElementInfo info, ArrayList entryNames) {
+	if (entryNames != null && entryNames.size() > 0) {
 		ArrayList vChildren = new ArrayList();
-		for (Iterator iter = jInfo.entryNames.iterator(); iter.hasNext();) {
+		for (Iterator iter = entryNames.iterator(); iter.hasNext();) {
 			String child = (String) iter.next();
 			IClassFile classFile = getClassFile(child);
 			vChildren.add(classFile);
@@ -65,22 +64,26 @@
 		return;
 	}
 	int max = resNames.length;
-	Object[] res = new Object[max];
-	int index = 0;
-	for (int i = 0; i < max; i++) {
-		String resName = resNames[i];
-		// consider that a .java file is not a non-java resource (see bug 12246 Packages view shows .class and .java files when JAR has source)
-		if (!resName.toLowerCase().endsWith(SUFFIX_STRING_java)) {
-			if (!this.isDefaultPackage()) {
-				resName = this.getElementName().replace('.', '/') + "/" + resName;//$NON-NLS-1$
+	if (max == 0) {
+	    info.setNonJavaResources(JavaElementInfo.NO_NON_JAVA_RESOURCES);
+	} else {
+		Object[] res = new Object[max];
+		int index = 0;
+		for (int i = 0; i < max; i++) {
+			String resName = resNames[i];
+			// consider that a .java file is not a non-java resource (see bug 12246 Packages view shows .class and .java files when JAR has source)
+			if (!resName.toLowerCase().endsWith(SUFFIX_STRING_java)) {
+				if (!this.isDefaultPackage()) {
+					resName = this.getElementName().replace('.', '/') + "/" + resName;//$NON-NLS-1$
+				}
+				res[index++] = new JarEntryFile(resName, zipName);
 			}
-			res[index++] = new JarEntryFile(resName, zipName);
+		} 
+		if (index != max) {
+			System.arraycopy(res, 0, res = new Object[index], 0, index);
 		}
-	} 
-	if (index != max) {
-		System.arraycopy(res, 0, res = new Object[index], 0, index);
+		info.setNonJavaResources(res);
 	}
-	info.setNonJavaResources(res);
 }
 /**
  * Returns true if this fragment contains at least one java resource.
diff --git a/model/org/eclipse/jdt/internal/core/JarPackageFragmentInfo.java b/model/org/eclipse/jdt/internal/core/JarPackageFragmentInfo.java
index a003d69..f8dba53 100644
--- a/model/org/eclipse/jdt/internal/core/JarPackageFragmentInfo.java
+++ b/model/org/eclipse/jdt/internal/core/JarPackageFragmentInfo.java
@@ -10,35 +10,14 @@
  *******************************************************************************/
 package org.eclipse.jdt.internal.core;
 
-import java.util.ArrayList;
-
 /**
- * Element info for JarPackageFragments.  Caches the zip entry names
- * of the types (.class files) of the JarPackageFragment.  The entries
- * are used to compute the children of the JarPackageFragment.
+ * Element info for JarPackageFragments.
  */
 class JarPackageFragmentInfo extends PackageFragmentInfo {
-	/**
-	 * The names of the zip entries that are the class files associated
-	 * with this package fragment info in the JAR file of the JarPackageFragmentRootInfo.
-	 */
-	protected ArrayList entryNames;
-/**
- */
-boolean containsJavaResources() {
-	return this.entryNames != null && this.entryNames.size() != 0;
-}
 /**
  * Returns an array of non-java resources contained in the receiver.
  */
 Object[] getNonJavaResources() {
 	return this.nonJavaResources;
 }
-/**
- * Set the names of the zip entries that are the types associated
- * with this package fragment info in the JAR file of the JarPackageFragmentRootInfo.
- */
-protected void setEntryNames(ArrayList entries) {
-	this.entryNames = entries;
-}
 }
diff --git a/model/org/eclipse/jdt/internal/core/JarPackageFragmentRoot.java b/model/org/eclipse/jdt/internal/core/JarPackageFragmentRoot.java
index b312128..e631714 100644
--- a/model/org/eclipse/jdt/internal/core/JarPackageFragmentRoot.java
+++ b/model/org/eclipse/jdt/internal/core/JarPackageFragmentRoot.java
@@ -145,9 +145,6 @@
 				ArrayList[] entries= (ArrayList[]) packageFragToTypes.get(packName);
 				JarPackageFragment packFrag= (JarPackageFragment) getPackageFragment(packName);
 				JarPackageFragmentInfo fragInfo= new JarPackageFragmentInfo();
-				if (entries[0].size() > 0){
-					fragInfo.setEntryNames(entries[JAVA]);
-				}
 				int resLength= entries[NON_JAVA].size();
 				if (resLength == 0) {
 					packFrag.computeNonJavaResources(NO_STRINGS, fragInfo, jar.getName());
@@ -156,7 +153,7 @@
 					entries[NON_JAVA].toArray(resNames);
 					packFrag.computeNonJavaResources(resNames, fragInfo, jar.getName());
 				}
-				packFrag.computeChildren(fragInfo);
+				packFrag.computeChildren(fragInfo, entries[JAVA]);
 				newElements.put(packFrag, fragInfo);
 				vChildren.add(packFrag);
 			}
diff --git a/model/org/eclipse/jdt/internal/core/JavaElementDelta.java b/model/org/eclipse/jdt/internal/core/JavaElementDelta.java
index 69c6fb7..76dc45c 100644
--- a/model/org/eclipse/jdt/internal/core/JavaElementDelta.java
+++ b/model/org/eclipse/jdt/internal/core/JavaElementDelta.java
@@ -675,6 +675,18 @@
 		buffer.append("PRIMARY RESOURCE"); //$NON-NLS-1$
 		prev = true;
 	}
+	if ((flags & IJavaElementDelta.F_OPENED) != 0) {
+		if (prev)
+			buffer.append(" | "); //$NON-NLS-1$
+		buffer.append("OPENED"); //$NON-NLS-1$
+		prev = true;
+	}
+	if ((flags & IJavaElementDelta.F_CLOSED) != 0) {
+		if (prev)
+			buffer.append(" | "); //$NON-NLS-1$
+		buffer.append("CLOSED"); //$NON-NLS-1$
+		prev = true;
+	}
 	return prev;
 }
 /** 
diff --git a/model/org/eclipse/jdt/internal/core/JavaModelManager.java b/model/org/eclipse/jdt/internal/core/JavaModelManager.java
index 107767f..f16450c 100644
--- a/model/org/eclipse/jdt/internal/core/JavaModelManager.java
+++ b/model/org/eclipse/jdt/internal/core/JavaModelManager.java
@@ -226,12 +226,13 @@
 	
 			if (container == null) {
 				projectContainers.remove(containerPath);
-				Map previousContainers = (Map)this.previousSessionContainers.get(project);
-				if (previousContainers != null){
-					previousContainers.remove(containerPath);
-				}
 			} else {
-				projectContainers.put(containerPath, container);
+   				projectContainers.put(containerPath, container);
+			}
+			// discard obsoleted information about previous session
+			Map previousContainers = (Map)this.previousSessionContainers.get(project);
+			if (previousContainers != null){
+				previousContainers.remove(containerPath);
 			}
 		}
 		// container values are persisted in preferences during save operations, see #saving(ISaveContext)
@@ -1206,20 +1207,31 @@
 		this.containerInitializationInProgress.set(allContainerPaths);
 		
 		// initialize all containers
-		Set keys = allContainerPaths.keySet();
-		int length = keys.size();
-		IJavaProject[] javaProjects = new IJavaProject[length]; // clone as the following will have a side effect
-		keys.toArray(javaProjects);
-		for (int i = 0; i < length; i++) {
-			IJavaProject javaProject = javaProjects[i];
-			HashSet pathSet = (HashSet) allContainerPaths.get(javaProject);
-			if (pathSet == null) continue;
-			int length2 = pathSet.size();
-			IPath[] paths = new IPath[length2];
-			pathSet.toArray(paths); // clone as the following will have a side effect
-			for (int j = 0; j < length2; j++) {
-				IPath path = paths[j];
-				initializeContainer(javaProject, path);
+		boolean ok = false;
+		try {
+			Set keys = allContainerPaths.keySet();
+			int length = keys.size();
+			IJavaProject[] javaProjects = new IJavaProject[length]; // clone as the following will have a side effect
+			keys.toArray(javaProjects);
+			for (int i = 0; i < length; i++) {
+				IJavaProject javaProject = javaProjects[i];
+				HashSet pathSet = (HashSet) allContainerPaths.get(javaProject);
+				if (pathSet == null) continue;
+				int length2 = pathSet.size();
+				IPath[] paths = new IPath[length2];
+				pathSet.toArray(paths); // clone as the following will have a side effect
+				for (int j = 0; j < length2; j++) {
+					IPath path = paths[j];
+					initializeContainer(javaProject, path);
+				}
+			}
+			ok = true;
+		} finally {
+			if (!ok) { 
+				// if we're being traversed by an exception, ensure that that containers are 
+				// no longer marked as initialization in progress
+				// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=66437)
+				this.containerInitializationInProgress.set(null);
 			}
 		}
 		
@@ -2050,10 +2062,11 @@
 			// update cache - do not only rely on listener refresh		
 			if (variablePath == null) {
 				this.variables.remove(variableName);
-				this.previousSessionVariables.remove(variableName);
 			} else {
 				this.variables.put(variableName, variablePath);
 			}
+			// discard obsoleted information about previous session
+			this.previousSessionVariables.remove(variableName);
 		}
 
 		String variableKey = CP_VARIABLE_PREFERENCES_PREFIX+variableName;
diff --git a/model/org/eclipse/jdt/internal/core/JavaProject.java b/model/org/eclipse/jdt/internal/core/JavaProject.java
index 71a704d..5d8fa0c 100644
--- a/model/org/eclipse/jdt/internal/core/JavaProject.java
+++ b/model/org/eclipse/jdt/internal/core/JavaProject.java
@@ -242,9 +242,9 @@
 	protected void addToBuildSpec(String builderID) throws CoreException {
 
 		IProjectDescription description = this.project.getDescription();
-		ICommand javaCommand = getJavaCommand(description);
+		int javaCommandIndex = getJavaCommandIndex(description.getBuildSpec());
 
-		if (javaCommand == null) {
+		if (javaCommandIndex == -1) {
 
 			// Add a Java command to the build spec
 			ICommand command = description.newCommand();
@@ -1373,17 +1373,17 @@
 	}
 
 	/**
-	 * Find the specific Java command amongst the build spec of a given description
+	 * Find the specific Java command amongst the given build spec
+	 * and return its index or -1 if not found.
 	 */
-	private ICommand getJavaCommand(IProjectDescription description) {
+	private int getJavaCommandIndex(ICommand[] buildSpec) {
 
-		ICommand[] commands = description.getBuildSpec();
-		for (int i = 0; i < commands.length; ++i) {
-			if (commands[i].getBuilderName().equals(JavaCore.BUILDER_ID)) {
-				return commands[i];
+		for (int i = 0; i < buildSpec.length; ++i) {
+			if (buildSpec[i].getBuilderName().equals(JavaCore.BUILDER_ID)) {
+				return i;
 			}
 		}
-		return null;
+		return -1;
 	}
 
 	/**
@@ -2520,23 +2520,18 @@
 		ICommand newCommand)
 		throws CoreException {
 
-		ICommand[] oldCommands = description.getBuildSpec();
-		ICommand oldJavaCommand = getJavaCommand(description);
+		ICommand[] oldBuildSpec = description.getBuildSpec();
+		int oldJavaCommandIndex = getJavaCommandIndex(oldBuildSpec);
 		ICommand[] newCommands;
 
-		if (oldJavaCommand == null) {
+		if (oldJavaCommandIndex == -1) {
 			// Add a Java build spec before other builders (1FWJK7I)
-			newCommands = new ICommand[oldCommands.length + 1];
-			System.arraycopy(oldCommands, 0, newCommands, 1, oldCommands.length);
+			newCommands = new ICommand[oldBuildSpec.length + 1];
+			System.arraycopy(oldBuildSpec, 0, newCommands, 1, oldBuildSpec.length);
 			newCommands[0] = newCommand;
 		} else {
-			for (int i = 0, max = oldCommands.length; i < max; i++) {
-				if (oldCommands[i] == oldJavaCommand) {
-					oldCommands[i] = newCommand;
-					break;
-				}
-			}
-			newCommands = oldCommands;
+		    oldBuildSpec[oldJavaCommandIndex] = newCommand;
+			newCommands = oldBuildSpec;
 		}
 
 		// Commit the spec change into the project
@@ -2595,6 +2590,10 @@
 
 			// persist options
 			projectPreferences.flush();
+			if (newOptions == null) {
+				// Uncache preferences
+				JavaModelManager.getJavaModelManager().resetProjectPreferences(this);
+			}
 		} catch (BackingStoreException e) {
 			// problem with pref store - quietly ignore
 		}
diff --git a/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java b/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java
index 9df3469..4da7fe1 100644
--- a/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java
+++ b/model/org/eclipse/jdt/internal/core/PackageFragmentRoot.java
@@ -335,7 +335,7 @@
 /**
  * Compares two objects for equality;
  * for <code>PackageFragmentRoot</code>s, equality is having the
- * same <code>JavaModel</code>, same resources, and occurrence count.
+ * same parent, same resources, and occurrence count.
  *
  */
 public boolean equals(Object o) {
@@ -345,7 +345,8 @@
 		return false;
 	PackageFragmentRoot other = (PackageFragmentRoot) o;
 	return this.resource.equals(other.resource) &&
-			this.occurrenceCount == other.occurrenceCount;
+			this.occurrenceCount == other.occurrenceCount && 
+			this.parent.equals(other.parent);
 }
 
 /**
@@ -832,19 +833,19 @@
  */
 protected void toStringInfo(int tab, StringBuffer buffer, Object info) {
 	buffer.append(this.tabString(tab));
-	if (getElementName().length() == 0) {
-		buffer.append("<project root>"); //$NON-NLS-1$
-	} else {
-		IPath path = getPath();
-		if (getJavaProject().getElementName().equals(path.segment(0))) {
+	IPath path = getPath();
+	if (getJavaProject().getElementName().equals(path.segment(0))) {
+	    if (path.segmentCount() == 1) {
+	buffer.append("<project root>"); //$NON-NLS-1$
+	    } else {
 			buffer.append(path.removeFirstSegments(1).makeRelative());
-		} else {
-		    if (isExternal()) {
-				buffer.append(path.toOSString());
-		    } else {
-				buffer.append(path);
-		    }
-		}
+	    }
+	} else {
+	    if (isExternal()) {
+			buffer.append(path.toOSString());
+	    } else {
+			buffer.append(path);
+	    }
 	}
 	if (info == null) {
 		buffer.append(" (not open)"); //$NON-NLS-1$
diff --git a/model/org/eclipse/jdt/internal/core/ReconcileWorkingCopyOperation.java b/model/org/eclipse/jdt/internal/core/ReconcileWorkingCopyOperation.java
index 438ec44..0def8a5 100644
--- a/model/org/eclipse/jdt/internal/core/ReconcileWorkingCopyOperation.java
+++ b/model/org/eclipse/jdt/internal/core/ReconcileWorkingCopyOperation.java
@@ -78,7 +78,7 @@
 							if (progressMonitor != null) progressMonitor.worked(1);
 							if (this.createAST && unit != null) {
 								Map options = workingCopy.getJavaProject().getOptions(true);
-								this.ast = AST.convertCompilationUnit(this.astLevel, unit, contents, options, this.progressMonitor);
+								this.ast = AST.convertCompilationUnit(this.astLevel, unit, contents, options, true/*isResolved*/, this.progressMonitor);
 								if (progressMonitor != null) progressMonitor.worked(1);
 							}
 					    } finally {
diff --git a/model/org/eclipse/jdt/internal/core/SelectionRequestor.java b/model/org/eclipse/jdt/internal/core/SelectionRequestor.java
index 9102ec7..e701cc1 100644
--- a/model/org/eclipse/jdt/internal/core/SelectionRequestor.java
+++ b/model/org/eclipse/jdt/internal/core/SelectionRequestor.java
@@ -17,6 +17,7 @@
 import org.eclipse.jdt.core.IJavaElement;
 import org.eclipse.jdt.core.IMethod;
 import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.ISourceRange;
 import org.eclipse.jdt.core.IType;
 import org.eclipse.jdt.core.JavaModelException;
 import org.eclipse.jdt.core.Signature;
@@ -145,7 +146,7 @@
 		}
 	}
 }
-public void acceptLocalMethod(SourceTypeBinding typeBinding, char[] selector, char[][] parameterPackageNames, char[][] parameterTypeNames, boolean isConstructor, CompilationUnitDeclaration parsedUnit) {
+public void acceptLocalMethod(SourceTypeBinding typeBinding, char[] selector, char[][] parameterPackageNames, char[][] parameterTypeNames, boolean isConstructor, CompilationUnitDeclaration parsedUnit, boolean isDeclaration, int start, int end) {
 	IType type = (IType)this.handleFactory.createElement(typeBinding.scope.referenceContext, parsedUnit, this.openable);
 	// fix for 1FWFT6Q
 	if (type != null) {
@@ -172,7 +173,7 @@
 			
 			acceptBinaryMethod(type, selector, parameterPackageNames, parameterTypeNames);
 		} else {
-			acceptSourceMethod(type, selector, parameterPackageNames, parameterTypeNames);
+			acceptSourceMethod(type, selector, parameterPackageNames, parameterTypeNames, isDeclaration, start, end);
 		}
 	}
 }
@@ -201,7 +202,7 @@
 /**
  * Resolve the method
  */
-public void acceptMethod(char[] declaringTypePackageName, char[] declaringTypeName, char[] selector, char[][] parameterPackageNames, char[][] parameterTypeNames, boolean isConstructor) {
+public void acceptMethod(char[] declaringTypePackageName, char[] declaringTypeName, char[] selector, char[][] parameterPackageNames, char[][] parameterTypeNames, boolean isConstructor, boolean isDeclaration, int start, int end) {
 	IType type= resolveType(declaringTypePackageName, declaringTypeName,
 		NameLookup.ACCEPT_CLASSES | NameLookup.ACCEPT_INTERFACES);
 	// fix for 1FWFT6Q
@@ -229,7 +230,7 @@
 			
 			acceptBinaryMethod(type, selector, parameterPackageNames, parameterTypeNames);
 		} else {
-			acceptSourceMethod(type, selector, parameterPackageNames, parameterTypeNames);
+			acceptSourceMethod(type, selector, parameterPackageNames, parameterTypeNames, isDeclaration, start, end);
 		}
 	}
 }
@@ -254,14 +255,21 @@
  *
  * fix for 1FWFT6Q
  */
-protected void acceptSourceMethod(IType type, char[] selector, char[][] parameterPackageNames, char[][] parameterTypeNames) {
+protected void acceptSourceMethod(IType type, char[] selector, char[][] parameterPackageNames, char[][] parameterTypeNames, boolean isDeclaration, int start, int end) {
 	String name = new String(selector);
 	IMethod[] methods = null;
 	try {
 		methods = type.getMethods();
 		for (int i = 0; i < methods.length; i++) {
 			if (methods[i].getElementName().equals(name) && methods[i].getParameterTypes().length == parameterTypeNames.length) {
-				addElement(methods[i]);
+				if(isDeclaration) {
+					ISourceRange range = methods[i].getNameRange();
+					if(range.getOffset() <= start && range.getOffset() + range.getLength() >= end) {
+						addElement(methods[i]);
+					}
+				} else {
+					addElement(methods[i]);
+				}
 			}
 		}
 	} catch (JavaModelException e) {
diff --git a/model/org/eclipse/jdt/internal/core/SourceType.java b/model/org/eclipse/jdt/internal/core/SourceType.java
index 8fb12ae..55a1801 100644
--- a/model/org/eclipse/jdt/internal/core/SourceType.java
+++ b/model/org/eclipse/jdt/internal/core/SourceType.java
@@ -741,7 +741,7 @@
 		public void acceptField(char[] declaringTypePackageName, char[] declaringTypeName, char[] fieldName) {
 			// ignore
 		}
-		public void acceptMethod(char[] declaringTypePackageName, char[] declaringTypeName, char[] selector, char[][] parameterPackageNames, char[][] parameterTypeNames, boolean isConstructor) {
+		public void acceptMethod(char[] declaringTypePackageName, char[] declaringTypeName, char[] selector, char[][] parameterPackageNames, char[][] parameterTypeNames, boolean isConstructor, boolean isDeclaration, int start, int end) {
 			// ignore
 		}
 		public void acceptPackage(char[] packageName){
diff --git a/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyResolver.java b/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyResolver.java
index 337ba9c..33e7a62 100644
--- a/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyResolver.java
+++ b/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyResolver.java
@@ -585,6 +585,7 @@
 					try {
 						IType[] topLevelTypes = cu.getTypes();
 						int topLevelLength = topLevelTypes.length;
+						if (topLevelLength == 0) continue; // empty cu: no need to parse (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=65677)
 						typeInfos = new SourceTypeElementInfo[topLevelLength];
 						for (int j = 0; j < topLevelLength; j++) {
 							IType topLevelType = topLevelTypes[j];
diff --git a/model/org/eclipse/jdt/internal/core/util/PublicScanner.java b/model/org/eclipse/jdt/internal/core/util/PublicScanner.java
index 6713b43..d90b1ca 100644
--- a/model/org/eclipse/jdt/internal/core/util/PublicScanner.java
+++ b/model/org/eclipse/jdt/internal/core/util/PublicScanner.java
@@ -199,6 +199,7 @@
 }
 
 // chech presence of task: tags
+// TODO (frederic) see if we need to take unicode characters into account...
 public void checkTaskTag(int commentStart, int commentEnd) {
 	char[] src = this.source;
 	
@@ -495,23 +496,17 @@
 			//need the unicode buffer
 			if (this.withoutUnicodePtr == 0) {
 				//buffer all the entries that have been left aside....
-				this.withoutUnicodePtr = this.currentPosition - unicodeSize - this.startPosition;
-				System.arraycopy(
-					this.source, 
-					this.startPosition, 
-					this.withoutUnicodeBuffer, 
-					1, 
-					this.withoutUnicodePtr); 
+			    unicodeInitializeBuffer(this.currentPosition - unicodeSize - this.startPosition);
 			}
 			//fill the buffer with the char
-			this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+			unicodeStoreAt(++this.withoutUnicodePtr);
 			return this.currentCharacter;
 
 		} //-------------end unicode traitement--------------
 		else {
 			this.unicodeAsBackSlash = false;
 			if (this.withoutUnicodePtr != 0) {
-				this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+			    unicodeStoreAt(++this.withoutUnicodePtr);
 			}
 			return this.currentCharacter;
 		}
@@ -567,16 +562,10 @@
 			//need the unicode buffer
 			if (this.withoutUnicodePtr == 0) {
 				//buffer all the entries that have been left aside....
-				this.withoutUnicodePtr = this.currentPosition - unicodeSize - this.startPosition;
-				System.arraycopy(
-					this.source, 
-					this.startPosition, 
-					this.withoutUnicodeBuffer, 
-					1, 
-					this.withoutUnicodePtr); 
+			    unicodeInitializeBuffer(this.currentPosition - unicodeSize - this.startPosition);
 			}
 			//fill the buffer with the char
-			this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+			unicodeStoreAt(++this.withoutUnicodePtr);
 			return true;
 
 		} //-------------end unicode traitement--------------
@@ -587,7 +576,7 @@
 			}
 			this.unicodeAsBackSlash = false;
 			if (this.withoutUnicodePtr != 0)
-				this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+				unicodeStoreAt(++this.withoutUnicodePtr);
 			return true;
 		}
 	} catch (IndexOutOfBoundsException e) {
@@ -647,16 +636,10 @@
 			//need the unicode buffer
 			if (this.withoutUnicodePtr == 0) {
 				//buffer all the entries that have been left aside....
-				this.withoutUnicodePtr = this.currentPosition - unicodeSize - this.startPosition;
-				System.arraycopy(
-					this.source, 
-					this.startPosition, 
-					this.withoutUnicodeBuffer, 
-					1, 
-					this.withoutUnicodePtr); 
+				unicodeInitializeBuffer(this.currentPosition - unicodeSize - this.startPosition);
 			}
 			//fill the buffer with the char
-			this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+			unicodeStoreAt(++this.withoutUnicodePtr);
 			return result;
 		} //-------------end unicode traitement--------------
 		else {
@@ -671,7 +654,7 @@
 				}
 
 			if (this.withoutUnicodePtr != 0)
-				this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+				unicodeStoreAt(++this.withoutUnicodePtr);
 			return result;
 		}
 	} catch (IndexOutOfBoundsException e) {
@@ -723,16 +706,10 @@
 			//need the unicode buffer
 			if (this.withoutUnicodePtr == 0) {
 				//buffer all the entries that have been left aside....
-				this.withoutUnicodePtr = this.currentPosition - unicodeSize - this.startPosition;
-				System.arraycopy(
-					this.source, 
-					this.startPosition, 
-					this.withoutUnicodeBuffer, 
-					1, 
-					this.withoutUnicodePtr); 
+				unicodeInitializeBuffer(this.currentPosition - unicodeSize - this.startPosition);
 			}
 			//fill the buffer with the char
-			this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+			unicodeStoreAt(++this.withoutUnicodePtr);
 			return true;
 		} //-------------end unicode traitement--------------
 		else {
@@ -741,7 +718,7 @@
 				return false;
 			}
 			if (this.withoutUnicodePtr != 0)
-				this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+				unicodeStoreAt(++this.withoutUnicodePtr);
 			return true;
 		}
 	} catch (IndexOutOfBoundsException e) {
@@ -793,16 +770,10 @@
 			//need the unicode buffer
 			if (this.withoutUnicodePtr == 0) {
 				//buffer all the entries that have been left aside....
-				this.withoutUnicodePtr = this.currentPosition - unicodeSize - this.startPosition;
-				System.arraycopy(
-					this.source, 
-					this.startPosition, 
-					this.withoutUnicodeBuffer, 
-					1, 
-					this.withoutUnicodePtr); 
+				unicodeInitializeBuffer(this.currentPosition - unicodeSize - this.startPosition);
 			}
 			//fill the buffer with the char
-			this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+			unicodeStoreAt(++this.withoutUnicodePtr);
 			return true;
 		} //-------------end unicode traitement--------------
 		else {
@@ -811,7 +782,7 @@
 				return false;
 			}
 			if (this.withoutUnicodePtr != 0)
-				this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+				unicodeStoreAt(++this.withoutUnicodePtr);
 			return true;
 		}
 	} catch (IndexOutOfBoundsException e) {
@@ -863,16 +834,10 @@
 			//need the unicode buffer
 			if (this.withoutUnicodePtr == 0) {
 				//buffer all the entries that have been left aside....
-				this.withoutUnicodePtr = this.currentPosition - unicodeSize - this.startPosition;
-				System.arraycopy(
-					this.source, 
-					this.startPosition, 
-					this.withoutUnicodeBuffer, 
-					1, 
-					this.withoutUnicodePtr); 
+				unicodeInitializeBuffer(this.currentPosition - unicodeSize - this.startPosition);
 			}
 			//fill the buffer with the char
-			this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+		    unicodeStoreAt(++this.withoutUnicodePtr);
 			return true;
 		} //-------------end unicode traitement--------------
 		else {
@@ -882,7 +847,7 @@
 			}
 
 			if (this.withoutUnicodePtr != 0)
-				this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+			    unicodeStoreAt(++this.withoutUnicodePtr);
 			return true;
 		}
 	} catch (IndexOutOfBoundsException e) {
@@ -1118,7 +1083,7 @@
 							getNextUnicodeChar();
 						} else {
 							if (this.withoutUnicodePtr != 0) {
-								this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+								unicodeStoreAt(++this.withoutUnicodePtr);
 							}
 						}
 					}
@@ -1147,7 +1112,7 @@
 							isUnicode = true;
 						} else {
 							if (this.withoutUnicodePtr != 0) {
-								this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+								unicodeStoreAt(++this.withoutUnicodePtr);
 							}
 						}
 
@@ -1189,16 +1154,10 @@
 								escapeSize = this.currentPosition - escapeSize;
 								if (this.withoutUnicodePtr == 0) {
 									//buffer all the entries that have been left aside....
-									this.withoutUnicodePtr = this.currentPosition - escapeSize - 1 - this.startPosition;
-									System.arraycopy(
-										this.source, 
-										this.startPosition, 
-										this.withoutUnicodeBuffer, 
-										1, 
-										this.withoutUnicodePtr); 
-									this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+								    unicodeInitializeBuffer(this.currentPosition - escapeSize - 1 - this.startPosition);
+								    unicodeStoreAt(++this.withoutUnicodePtr);
 								} else { //overwrite the / in the buffer
-									this.withoutUnicodeBuffer[this.withoutUnicodePtr] = this.currentCharacter;
+								    unicodeStoreAt(this.withoutUnicodePtr);
 									if (backSlashAsUnicodeInString) { //there are TWO \ in the stream where only one is correct
 										this.withoutUnicodePtr--;
 									}
@@ -1211,7 +1170,7 @@
 								getNextUnicodeChar();
 							} else {
 								if (this.withoutUnicodePtr != 0) {
-									this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+									unicodeStoreAt(++this.withoutUnicodePtr);
 								}
 							}
 
@@ -1393,7 +1352,7 @@
 								} else {
 									isUnicode = false;
 									if (this.withoutUnicodePtr != 0) {
-										this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+										unicodeStoreAt(++this.withoutUnicodePtr);
 									}
 								}
 	
@@ -1535,16 +1494,10 @@
 			//need the unicode buffer
 			if (this.withoutUnicodePtr == 0) {
 				//buffer all the entries that have been left aside....
-				this.withoutUnicodePtr = this.currentPosition - unicodeSize - this.startPosition;
-				System.arraycopy(
-					this.source, 
-					this.startPosition, 
-					this.withoutUnicodeBuffer, 
-					1, 
-					this.withoutUnicodePtr); 
+				unicodeInitializeBuffer(this.currentPosition - unicodeSize - this.startPosition);
 			}
 			//fill the buffer with the char
-			this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+			unicodeStoreAt(++this.withoutUnicodePtr);
 		}
 		this.unicodeAsBackSlash = this.currentCharacter == '\\';
 	} catch (ArrayIndexOutOfBoundsException e) {
@@ -1608,7 +1561,7 @@
 									getNextUnicodeChar();
 								} else {
 									if (this.withoutUnicodePtr != 0) {
-										this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+										unicodeStoreAt(++this.withoutUnicodePtr);
 									}
 								}
 							} catch (InvalidInputException ex) {
@@ -1627,7 +1580,7 @@
 								getNextUnicodeChar();
 							} else {
 								if (this.withoutUnicodePtr != 0) {
-									this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+								    unicodeStoreAt(++this.withoutUnicodePtr);
 								}
 							}
 						} catch (InvalidInputException ex) {
@@ -1655,7 +1608,7 @@
 									getNextUnicodeChar();
 								} else {
 									if (this.withoutUnicodePtr != 0) {
-										this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+										unicodeStoreAt(++this.withoutUnicodePtr);
 									}
 								}
 							} catch (InvalidInputException ex) {
@@ -1804,7 +1757,7 @@
 								} else {
 									isUnicode = false;
 									if (this.withoutUnicodePtr != 0) {
-										this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+    								    unicodeStoreAt(++this.withoutUnicodePtr);
 									}
 								}
 	
@@ -1932,7 +1885,7 @@
 			return true;
 
 		//buffer the new char which is not a white space
-		this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+		unicodeStoreAt(++this.withoutUnicodePtr);
 		//this.withoutUnicodePtr == 1 is true here
 		return false;
 	} catch (IndexOutOfBoundsException e){
@@ -2359,7 +2312,7 @@
 			getNextUnicodeChar();
 		} else {
 			if (this.withoutUnicodePtr != 0) {
-				this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+				unicodeStoreAt(++this.withoutUnicodePtr);
 			}
 		}
 	} else
@@ -3017,7 +2970,7 @@
 				getNextUnicodeChar();
 			} else {
 				if (this.withoutUnicodePtr != 0) {
-					this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+					unicodeStoreAt(++this.withoutUnicodePtr);
 				}
 			}
 			if (Character.digit(this.currentCharacter, 16) == -1)
@@ -3059,7 +3012,7 @@
 						getNextUnicodeChar();
 					} else {
 						if (this.withoutUnicodePtr != 0) {
-							this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+							unicodeStoreAt(++this.withoutUnicodePtr);
 						}
 					}
 
@@ -3071,7 +3024,7 @@
 							getNextUnicodeChar();
 						} else {
 							if (this.withoutUnicodePtr != 0) {
-								this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+								unicodeStoreAt(++this.withoutUnicodePtr);
 							}
 						}
 					}
@@ -3111,7 +3064,7 @@
 			getNextUnicodeChar();
 		} else {
 			if (this.withoutUnicodePtr != 0) {
-				this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+				unicodeStoreAt(++this.withoutUnicodePtr);
 			}
 		}
 
@@ -3123,7 +3076,7 @@
 				getNextUnicodeChar();
 			} else {
 				if (this.withoutUnicodePtr != 0) {
-					this.withoutUnicodeBuffer[++this.withoutUnicodePtr] = this.currentCharacter;
+					unicodeStoreAt(++this.withoutUnicodePtr);
 				}
 			}
 		}
@@ -3185,7 +3138,6 @@
 	this.eofPosition = sourceLength;
 	this.initialPosition = this.currentPosition = 0;
 	this.containsAssertKeyword = false;
-	this.withoutUnicodeBuffer = new char[sourceLength]; // TODO (philippe) should only allocate when needed
 }
 
 public String toString() {
@@ -3437,4 +3389,21 @@
 			return "not-a-token"; //$NON-NLS-1$
 	}
 }
+public void unicodeInitializeBuffer(int length) {
+	this.withoutUnicodePtr = length;	
+    if (this.withoutUnicodeBuffer == null) this.withoutUnicodeBuffer = new char[length+(1+10)];
+    int bLength = this.withoutUnicodeBuffer.length;
+    if (1+length >= bLength) {
+        System.arraycopy(this.withoutUnicodeBuffer, 0, this.withoutUnicodeBuffer = new char[length + (1+10)], 0, bLength);
+    }
+	System.arraycopy(this.source, this.startPosition, this.withoutUnicodeBuffer, 1, length);    
+}
+public void unicodeStoreAt(int pos) {
+    if (this.withoutUnicodeBuffer == null) this.withoutUnicodeBuffer = new char[10];
+    int length = this.withoutUnicodeBuffer.length;
+    if (pos == length) {
+        System.arraycopy(this.withoutUnicodeBuffer, 0, this.withoutUnicodeBuffer = new char[length * 2], 0, length);
+    }
+	this.withoutUnicodeBuffer[pos] = this.currentCharacter;
+}
 }
diff --git a/model/org/eclipse/jdt/internal/core/util/messages.properties b/model/org/eclipse/jdt/internal/core/util/messages.properties
index 024383e..8670c8f 100644
--- a/model/org/eclipse/jdt/internal/core/util/messages.properties
+++ b/model/org/eclipse/jdt/internal/core/util/messages.properties
@@ -12,34 +12,34 @@
 ### JavaModel messages.
 
 ### hierarchy
-hierarchy.nullProject = Project argument cannot be null.
-hierarchy.nullRegion = Region cannot be null.
-hierarchy.nullFocusType = Type focus cannot be null.
+hierarchy.nullProject = Project argument cannot be null
+hierarchy.nullRegion = Region cannot be null
+hierarchy.nullFocusType = Type focus cannot be null
 hierarchy.creating = Creating type hierarchy...
 hierarchy.creatingOnType = Creating type hierarchy on {0}...
 
 ### java element
-element.doesNotExist = {0} does not exist.
-element.invalidClassFileName = Class file name must end with .class.
+element.doesNotExist = {0} does not exist
+element.invalidClassFileName = Class file name must end with .class
 element.reconciling = Reconciling...
 element.attachingSource = Attaching source...
-element.invalidType = Type is not one of the defined constants.
+element.invalidType = Type is not one of the defined constants
 element.invalidResourceForProject = Illegal argument - must be one of IProject, IFolder, or IFile
-element.nullName = Name cannot be null.
-element.nullType = Type cannot be null.
-element.illegalParent = Illegal parent argument.
+element.nullName = Name cannot be null
+element.nullType = Type cannot be null
+element.illegalParent = Illegal parent argument
 sourcetype.invalidName = The source type has an invalid name: {0}
 
 ### java model operations
-operation.needElements = Operation requires one or more elements.
-operation.needName = Operation requires a name.
-operation.needPath = Operation requires a path.
+operation.needElements = Operation requires one or more elements
+operation.needName = Operation requires a name
+operation.needPath = Operation requires a path
 operation.needAbsolutePath = Operation requires an absolute path. Relative path specified was: ''{0}''
 operation.needString = Operation requires a String.
 operation.notSupported = Operation not supported for specified element type(s):
-operation.cancelled = Operation cancelled.
-operation.nullContainer = Container cannot be null.
-operation.nullName = Name cannot be null.
+operation.cancelled = Operation cancelled
+operation.nullContainer = Container cannot be null
+operation.nullName = Name cannot be null
 operation.copyElementProgress = Copying elements...
 operation.moveElementProgress = Moving elements...
 operation.renameElementProgress = Renaming elements...
@@ -56,7 +56,7 @@
 operation.createTypeProgress = Creating a type...
 operation.deleteElementProgress = Deleting elements...
 operation.deleteResourceProgress = Deleting resources...
-operation.cannotRenameDefaultPackage = Default package cannot be renamed.
+operation.cannotRenameDefaultPackage = Default package cannot be renamed
 operation.pathOutsideProject = Path ''{0}'' must denote location inside project {1}
 operation.sortelements = Sorting elements...
 
@@ -83,116 +83,118 @@
 build.done = Build done
 
 ### build errors
-build.wrongFileFormat = Wrong file format.
-build.cannotSaveState = Error saving last build state for project {0}.
-build.cannotSaveStates = Error saving build states.
-build.initializationError = Builder initialization error.
-build.serializationError = Builder serialization error.
+build.wrongFileFormat = Wrong file format
+build.cannotSaveState = Error saving last build state for project {0}
+build.cannotSaveStates = Error saving build states
+build.initializationError = Builder initialization error
+build.serializationError = Builder serialization error
 
 ### build inconsistencies
-build.classFileCollision = Class file collision. {0}
-build.duplicateClassFile = The type {0} is already defined.
-build.duplicateResource = The resource is a duplicate of {0} and was not copied to the output folder.
-build.inconsistentClassFile = A class file was not written. The project may be inconsistent, if so try refreshing this project and building it.
-build.inconsistentProject = The project was not built due to "{0}". Fix the problem, then try refreshing this project and building it since it may be inconsistent.
-build.incompleteClassPath = The project was not built since its build path is incomplete. Cannot find the class file for {0}. Fix the build path then try building this project.
-build.missingSourceFile = The project was not built since the source file {0} could not be read.
-build.prereqProjectHasClasspathProblems = The project was not built since it depends on {0}, which has build path errors.
-build.prereqProjectMustBeRebuilt = The project cannot be built until its prerequisite {0} is built. Cleaning and building all projects is recommended.
-build.abortDueToClasspathProblems = The project cannot be built until build path errors are resolved.
+build.classFileCollision = Class file collision: {0}
+build.duplicateClassFile = The type {0} is already defined
+build.duplicateResource = The resource is a duplicate of {0} and was not copied to the output folder
+build.inconsistentClassFile = A class file was not written. The project may be inconsistent, if so try refreshing this project and building it
+build.inconsistentProject = The project was not built due to "{0}". Fix the problem, then try refreshing this project and building it since it may be inconsistent
+build.incompleteClassPath = The project was not built since its build path is incomplete. Cannot find the class file for {0}. Fix the build path then try building this project
+build.missingSourceFile = The project was not built since the source file {0} could not be read
+build.prereqProjectHasClasspathProblems = The project was not built since it depends on {0}, which has build path errors
+build.prereqProjectMustBeRebuilt = The project cannot be built until its prerequisite {0} is built. Cleaning and building all projects is recommended
+build.abortDueToClasspathProblems = The project cannot be built until build path errors are resolved
 
 ### status
 status.cannotUseDeviceOnPath = Operation requires a path with no device. Path specified was: {0}
-status.coreException = Core exception.
-status.defaultPackageReadOnly = Default package is read-only.
-status.evaluationError = Evaluation error: {0}.
-status.JDOMError = JDOM error.
-status.IOException = I/O exception.
-status.indexOutOfBounds = Index out of bounds.
-status.invalidContents = Invalid contents specified.
-status.invalidDestination = Invalid destination: ''{0}''.
-status.invalidName = Invalid name specified: {0}.
-status.invalidPackage = Invalid package: {0}.
-status.invalidPath = Invalid path: ''{0}''.
-status.invalidProject = Invalid project: {0}.
-status.invalidResource = Invalid resource: {0}.
-status.invalidResourceType = Invalid resource type for {0}.
-status.invalidSibling = Invalid sibling: {0}.
-status.nameCollision = {0} already exists in target.
+status.coreException = Core exception
+status.defaultPackageReadOnly = Default package is read-only
+status.evaluationError = Evaluation error: {0}
+status.JDOMError = JDOM error
+status.IOException = I/O exception
+status.indexOutOfBounds = Index out of bounds
+status.invalidContents = Invalid contents specified
+status.invalidDestination = Invalid destination: ''{0}''
+status.invalidName = Invalid name specified: {0}
+status.invalidPackage = Invalid package: {0}
+status.invalidPath = Invalid path: ''{0}''
+status.invalidProject = Invalid project: {0}
+status.invalidResource = Invalid resource: {0}
+status.invalidResourceType = Invalid resource type for {0}
+status.invalidSibling = Invalid sibling: {0}
+status.nameCollision = {0} already exists in target
 status.noLocalContents = Cannot find local contents for resource: {0}
 status.OK = OK
-status.readOnly = {0} is read-only.
-status.targetException = Target exception.
-status.updateConflict = Update conflict.
+status.readOnly = {0} is read-only
+status.targetException = Target exception
+status.updateConflict = Update conflict
 
 ### classpath
 classpath.buildPath = Build path
-classpath.cannotNestEntryInEntry = Cannot nest ''{0}'' inside ''{1}''. To enable the nesting exclude ''{2}'' from ''{1}''.
-classpath.cannotNestEntryInLibrary = Cannot nest ''{0}'' inside library ''{1}''.
-classpath.cannotNestEntryInOutput = Cannot nest ''{0}'' inside output folder ''{1}''.
-classpath.cannotNestOutputInEntry = Cannot nest output folder ''{0}'' inside ''{1}''.
-classpath.cannotNestOutputInOutput = Cannot nest output folder ''{0}'' inside output folder ''{1}''.
-classpath.cannotReadClasspathFile = Unable to read ''.classpath'' file of project {0}.
+classpath.cannotNestEntryInEntry = Cannot nest ''{0}'' inside ''{1}''. To enable the nesting exclude ''{2}'' from ''{1}''
+classpath.cannotNestEntryInLibrary = Cannot nest ''{0}'' inside library ''{1}''
+classpath.cannotNestEntryInOutput = Cannot nest ''{0}'' inside output folder ''{1}''
+classpath.cannotNestOutputInEntry = Cannot nest output folder ''{0}'' inside ''{1}''
+classpath.cannotNestOutputInOutput = Cannot nest output folder ''{0}'' inside output folder ''{1}''
+classpath.cannotReadClasspathFile = Unable to read ''.classpath'' file of project {0}
 classpath.cannotReferToItself = Project cannot reference itself: {0}
-classpath.cannotUseDistinctSourceFolderAsOutput = Source folder ''{0}'' in project {2} cannot output to distinct source folder ''{1}''.
-classpath.cannotUseLibraryAsOutput = Source folder ''{0}'' in project {2} cannot output to library ''{1}''.
-classpath.closedProject = Required project: {0} needs to be open.
+classpath.cannotUseDistinctSourceFolderAsOutput = Source folder ''{0}'' in project {2} cannot output to distinct source folder ''{1}''
+classpath.cannotUseLibraryAsOutput = Source folder ''{0}'' in project {2} cannot output to library ''{1}''
+classpath.closedProject = Required project: {0} needs to be open
 classpath.couldNotWriteClasspathFile = Could not write ''.classpath'' file of project {0}: {1}
 classpath.cycle = A cycle was detected in the build path of project: {0}
 classpath.duplicateEntryPath = Build path contains duplicate entry: ''{0}'' for project {1}
-classpath.illegalContainerPath = Illegal classpath container path: ''{0}'' in project {1}, must have at least one segment (containerID+hints).
+classpath.illegalContainerPath = Illegal classpath container path: ''{0}'' in project {1}, must have at least one segment (containerID+hints)
 classpath.illegalEntryInClasspathFile = Illegal entry in ''.classpath'' of project {0} file: {1}
-classpath.illegalLibraryPath = Illegal path for required library: ''{0}'' in project {1}.
-classpath.illegalProjectPath = Illegal path for required project: ''{0}'' in project {1}.
-classpath.illegalSourceFolderPath = Illegal path for required source folder: ''{0}'' in project {1}.
-classpath.illegalVariablePath = Illegal classpath variable path: ''{0}'' in project {1}, must have at least one segment.
+classpath.illegalLibraryPath = Illegal path for required library: ''{0}'' in project {1}
+classpath.illegalLibraryArchive = Illegal type of archive for required library: ''{0}'' in project {1}
+classpath.illegalExternalFolder = Required library cannot denote external folder: ''{0}'' for project {1}
+classpath.illegalProjectPath = Illegal path for required project: ''{0}'' in project {1}
+classpath.illegalSourceFolderPath = Illegal path for required source folder: ''{0}'' in project {1}
+classpath.illegalVariablePath = Illegal classpath variable path: ''{0}'' in project {1}, must have at least one segment
 classpath.invalidClasspathInClasspathFile = Invalid build path in ''.classpath'' file of project {0}: {1}
-classpath.invalidContainer = Invalid classpath container: ''{0}'' in project {1}.
-classpath.mustEndWithSlash = End exclusion filter ''{0}'' with / to fully exclude ''{1}''.
-classpath.unboundContainerPath = Unbound classpath container: ''{0}'' in project {1}.
-classpath.unboundLibrary = Project {1} is missing required library: ''{0}''.
-classpath.unboundProject = Project {1} is missing required Java project: ''{0}''.
+classpath.invalidContainer = Invalid classpath container: ''{0}'' in project {1}
+classpath.mustEndWithSlash = End exclusion filter ''{0}'' with / to fully exclude ''{1}''
+classpath.unboundContainerPath = Unbound classpath container: ''{0}'' in project {1}
+classpath.unboundLibrary = Project {1} is missing required library: ''{0}''
+classpath.unboundProject = Project {1} is missing required Java project: ''{0}''
 classpath.settingOutputLocationProgress = Setting output location for: ''{0}''
 classpath.settingProgress = Setting classpath for: {0}
-classpath.unboundSourceAttachment = Invalid source attachment: ''{0}'' for required library ''{1}'' in project {1}.
-classpath.unboundSourceFolder = Project {1} is missing required source folder: ''{0}''.
-classpath.unboundVariablePath = Unbound classpath variable: ''{0}'' in project {1}.
+classpath.unboundSourceAttachment = Invalid source attachment: ''{0}'' for required library ''{1}'' in project {1}
+classpath.unboundSourceFolder = Project {1} is missing required source folder: ''{0}''
+classpath.unboundVariablePath = Unbound classpath variable: ''{0}'' in project {1}
 classpath.unknownKind = Unknown kind: ''{0}''
 classpath.xmlFormatError = XML format error in ''.classpath'' file of project {0}: {1}
-classpath.disabledInclusionExclusionPatterns = Inclusion or exclusion patterns are disabled in project {1}, cannot selectively include or exclude from entry: ''{0}''.
-classpath.disabledMultipleOutputLocations = Multiple output locations are disabled in project {1}, cannot associate entry: ''{0}'' with a specific output.
-classpath.incompatibleLibraryJDKLevel = Incompatible .class files version in required binaries. Project ''{0}'' is targeting a {1} runtime, but is compiled against ''{2}'' which requires a {3} runtime.
+classpath.disabledInclusionExclusionPatterns = Inclusion or exclusion patterns are disabled in project {1}, cannot selectively include or exclude from entry: ''{0}''
+classpath.disabledMultipleOutputLocations = Multiple output locations are disabled in project {1}, cannot associate entry: ''{0}'' with a specific output
+classpath.incompatibleLibraryJDKLevel = Incompatible .class files version in required binaries. Project ''{0}'' is targeting a {1} runtime, but is compiled against ''{2}'' which requires a {3} runtime
 
 ### miscellaneous
-file.notFound = File not found: ''{0}''.
-file.badFormat = Bad format.
-path.nullPath = Path cannot be null.
-path.mustBeAbsolute = Path must be absolute.
+file.notFound = File not found: ''{0}''
+file.badFormat = Bad format
+path.nullPath = Path cannot be null
+path.mustBeAbsolute = Path must be absolute
 cache.invalidLoadFactor = Incorrect load factor
 savedState.jobName = Processing Java changes since last activation
 
 ### java conventions
-convention.unit.nullName = Compilation unit name must not be null.
-convention.unit.notJavaName = Compilation unit name must end with .java.
-convention.classFile.nullName = .class file name must not be null.
-convention.classFile.notClassFileName = .class file name must end with .class.
-convention.illegalIdentifier = ''{0}'' is not a valid Java identifier.
-convention.import.nullImport = An import declaration must not be null.
-convention.import.unqualifiedImport = An import declaration must not end with an unqualified *.
-convention.type.nullName = A Java type name must not be null.
-convention.type.nameWithBlanks = A Java type name must not start or end with a blank.
-convention.type.dollarName = By convention, Java type names usually don''t contain the $ character.
-convention.type.lowercaseName = By convention, Java type names usually start with an uppercase letter.
-convention.type.invalidName = The type name ''{0}'' is not a valid identifier.
-convention.package.nullName = A package name must not be null.
-convention.package.emptyName = A package name must not be empty.
-convention.package.dotName = A package name cannot start or end with a dot.
-convention.package.nameWithBlanks = A package name must not start or end with a blank.
-convention.package.consecutiveDotsName = A package name must not contain two consecutive dots.
-convention.package.uppercaseName = By convention, package names usually start with a lowercase letter.
+convention.unit.nullName = Compilation unit name must not be null
+convention.unit.notJavaName = Compilation unit name must end with .java
+convention.classFile.nullName = .class file name must not be null
+convention.classFile.notClassFileName = .class file name must end with .class
+convention.illegalIdentifier = ''{0}'' is not a valid Java identifier
+convention.import.nullImport = An import declaration must not be null
+convention.import.unqualifiedImport = An import declaration must not end with an unqualified *
+convention.type.nullName = A Java type name must not be null
+convention.type.nameWithBlanks = A Java type name must not start or end with a blank
+convention.type.dollarName = By convention, Java type names usually don''t contain the $ character
+convention.type.lowercaseName = By convention, Java type names usually start with an uppercase letter
+convention.type.invalidName = The type name ''{0}'' is not a valid identifier
+convention.package.nullName = A package name must not be null
+convention.package.emptyName = A package name must not be empty
+convention.package.dotName = A package name cannot start or end with a dot
+convention.package.nameWithBlanks = A package name must not start or end with a blank
+convention.package.consecutiveDotsName = A package name must not contain two consecutive dots
+convention.package.uppercaseName = By convention, package names usually start with a lowercase letter
 
 ### DOM
-dom.cannotDetail = Unable to generate detailed source indexes.
+dom.cannotDetail = Unable to generate detailed source indexes
 dom.nullTypeParameter = Cannot add parameter with null type
 dom.nullNameParameter = Cannot add parameter with null name
 dom.nullReturnType = Return type cannot be null
@@ -212,8 +214,8 @@
 dom.nullInterfaces = Illegal to set super interfaces to null
 
 ### correction
-correction.nullRequestor = Requestor cannot be null.
-correction.nullUnit = Compilation unit cannot be null.
+correction.nullRequestor = Requestor cannot be null
+correction.nullUnit = Compilation unit cannot be null
 
 ### Eclipse Java Core Search messages.
 
diff --git a/search/org/eclipse/jdt/core/search/SearchEngine.java b/search/org/eclipse/jdt/core/search/SearchEngine.java
index d51b734..7426d74 100644
--- a/search/org/eclipse/jdt/core/search/SearchEngine.java
+++ b/search/org/eclipse/jdt/core/search/SearchEngine.java
@@ -408,7 +408,6 @@
 	 *		 <li><code>IJavaSearchConstants.IMPLEMENTORS</code>: for interface, will find all types which implements a given interface.</li>
 	 *	</ul>
 	 * @return a search pattern for a Java element or <code>null</code> if the given element is ill-formed
-	 * @deprecated use SearchPattern.createPattern(IJavaElement, int) instead
 	 * @deprecated Use {@link SearchPattern#createPattern(IJavaElement, int)} instead.
 	 */
 	public static ISearchPattern createSearchPattern(IJavaElement element, int limitTo) {
diff --git a/search/org/eclipse/jdt/core/search/SearchParticipant.java b/search/org/eclipse/jdt/core/search/SearchParticipant.java
index b7f1ee7..015958b 100644
--- a/search/org/eclipse/jdt/core/search/SearchParticipant.java
+++ b/search/org/eclipse/jdt/core/search/SearchParticipant.java
@@ -15,6 +15,7 @@
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.*;
 import org.eclipse.jdt.internal.core.JavaModelManager;
+import org.eclipse.jdt.internal.core.search.indexing.IndexManager;
 
 /**
  * A search participant describes a particular extension to a generic search
@@ -174,7 +175,11 @@
 		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
 		IResource resource = root.findMember(documentPath);
 		IPath containerPath = resource == null ? documentPath : resource.getProject().getFullPath();
-		JavaModelManager.getJavaModelManager().getIndexManager().scheduleDocumentIndexing(document, containerPath, indexLocation.toOSString(), this);
+		IndexManager manager = JavaModelManager.getJavaModelManager().getIndexManager();
+		String osIndexLocation = indexLocation.toOSString();
+		// TODO (jerome) should not have to create index manually, should expose API that recreates index instead
+		manager.ensureIndexExists(osIndexLocation, containerPath);
+		manager.scheduleDocumentIndexing(document, containerPath, osIndexLocation, this);
 	}
 
 	/**
diff --git a/search/org/eclipse/jdt/internal/core/index/DiskIndex.java b/search/org/eclipse/jdt/internal/core/index/DiskIndex.java
index e037d14..a9f684e 100644
--- a/search/org/eclipse/jdt/internal/core/index/DiskIndex.java
+++ b/search/org/eclipse/jdt/internal/core/index/DiskIndex.java
@@ -419,7 +419,7 @@
 	File newIndexFile = newDiskIndex.getIndexFile();
 	try {
 		newDiskIndex.initializeFrom(this, newIndexFile);
-		DataOutputStream stream = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(newIndexFile, false)));
+		DataOutputStream stream = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(newIndexFile, false), 2048));
 		int offsetToHeader = -1;
 		try {
 			newDiskIndex.writeAllDocumentNames(docNames, stream);
@@ -476,7 +476,7 @@
 	if (this.numberOfChunks <= 0)
 		return new String[0];
 
-	DataInputStream stream = new DataInputStream(new BufferedInputStream(new FileInputStream(getIndexFile())));
+	DataInputStream stream = new DataInputStream(new BufferedInputStream(new FileInputStream(getIndexFile()), 2048));
 	try {
 		stream.skip(this.chunkOffsets[0]);
 		int lastIndex = this.numberOfChunks - 1;
@@ -502,7 +502,7 @@
 			return cachedTable;
 	}
 
-	DataInputStream stream = new DataInputStream(new BufferedInputStream(new FileInputStream(getIndexFile())));
+	DataInputStream stream = new DataInputStream(new BufferedInputStream(new FileInputStream(getIndexFile()), 2048));
 	HashtableOfObject categoryTable = null;
 	char[][] matchingWords = null;
 	int count = 0;
@@ -533,7 +533,7 @@
 	}
 
 	if (count > 0) {
-		stream = new DataInputStream(new BufferedInputStream(new FileInputStream(getIndexFile())));
+		stream = new DataInputStream(new BufferedInputStream(new FileInputStream(getIndexFile()), 2048));
 		try {
 			stream.skip(firstOffset);
 			for (int i = 0; i < count; i++) // each array follows the previous one
@@ -593,7 +593,7 @@
 	int chunkNumber = docNumber / CHUNK_SIZE;
 	String[] chunk = this.cachedChunks[chunkNumber];
 	if (chunk == null) {
-		DataInputStream stream = new DataInputStream(new BufferedInputStream(new FileInputStream(getIndexFile())));
+		DataInputStream stream = new DataInputStream(new BufferedInputStream(new FileInputStream(getIndexFile()), 2048));
 		try {
 			stream.skip(this.chunkOffsets[chunkNumber]);
 			int size = chunkNumber == this.numberOfChunks - 1 ? this.sizeOfLastChunk : CHUNK_SIZE;
@@ -611,7 +611,7 @@
 	if (arrayOffset instanceof int[])
 		return (int[]) arrayOffset;
 
-	DataInputStream stream = new DataInputStream(new BufferedInputStream(new FileInputStream(getIndexFile())));
+	DataInputStream stream = new DataInputStream(new BufferedInputStream(new FileInputStream(getIndexFile()), 2048));
 	try {
 		stream.skip(((Integer) arrayOffset).intValue());
 		return readDocumentArray(stream);
diff --git a/search/org/eclipse/jdt/internal/core/search/indexing/AddFolderToIndex.java b/search/org/eclipse/jdt/internal/core/search/indexing/AddFolderToIndex.java
index ce04058..4df92c9 100644
--- a/search/org/eclipse/jdt/internal/core/search/indexing/AddFolderToIndex.java
+++ b/search/org/eclipse/jdt/internal/core/search/indexing/AddFolderToIndex.java
@@ -80,8 +80,11 @@
 									}
 									return false;
 								case IResource.FOLDER :
-									if (Util.isExcluded(proxy.requestResource(), inclusionPatterns, exclusionPatterns))
-										return false;
+									if (exclusionPatterns != null && inclusionPatterns == null) {
+										// if there are inclusion patterns then we must walk the children
+										if (Util.isExcluded(proxy.requestFullPath(), inclusionPatterns, exclusionPatterns, true)) 
+										    return false;
+									}
 							}
 							return true;
 						}
diff --git a/search/org/eclipse/jdt/internal/core/search/indexing/IndexAllProject.java b/search/org/eclipse/jdt/internal/core/search/indexing/IndexAllProject.java
index 6faae93..0c38803 100644
--- a/search/org/eclipse/jdt/internal/core/search/indexing/IndexAllProject.java
+++ b/search/org/eclipse/jdt/internal/core/search/indexing/IndexAllProject.java
@@ -115,9 +115,11 @@
 												}
 												return false;
 											case IResource.FOLDER :
-												if (exclusionPatterns != null || inclusionPatterns != null)
-													if (Util.isExcluded(proxy.requestResource(), inclusionPatterns, exclusionPatterns))
-														return false;
+												if (exclusionPatterns != null && inclusionPatterns == null) {
+													// if there are inclusion patterns then we must walk the children
+													if (Util.isExcluded(proxy.requestFullPath(), inclusionPatterns, exclusionPatterns, true)) 
+													    return false;
+												}
 												if (hasOutputs && outputs.contains(proxy.requestFullPath()))
 													return false;
 										}
diff --git a/search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java b/search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java
index f1f1f61..924d55b 100644
--- a/search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java
+++ b/search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java
@@ -143,6 +143,17 @@
 	}
 	return indexLocation;
 }
+/*
+ * Creates an empty index at the given location, for the given container path, if none exist.
+ */
+public void ensureIndexExists(String indexLocation, IPath containerPath) {
+	SimpleLookupTable states = getIndexStates();
+	Object state = states.get(indexLocation);
+	if (state == null) {
+		updateIndexState(indexLocation, REBUILDING_STATE);
+		getIndex(containerPath, indexLocation, true, true);
+	}
+}
 /**
  * Returns the index for a given project, according to the following algorithm:
  * - if index is already in memory: answers this one back
diff --git a/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java b/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java
index 2368899..5363313 100644
--- a/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java
+++ b/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java
@@ -357,6 +357,7 @@
 				this.options,
 				new DefaultProblemFactory());
 		this.basicParser = new Parser(problemReporter, false);
+		this.basicParser.reportOnlyOneSyntaxError = true;
 	}
 	return this.basicParser;
 }
diff --git a/search/org/eclipse/jdt/internal/core/search/matching/MatchLocatorParser.java b/search/org/eclipse/jdt/internal/core/search/matching/MatchLocatorParser.java
index edf754a..b753a73 100644
--- a/search/org/eclipse/jdt/internal/core/search/matching/MatchLocatorParser.java
+++ b/search/org/eclipse/jdt/internal/core/search/matching/MatchLocatorParser.java
@@ -85,7 +85,7 @@
 
 protected MatchLocatorParser(ProblemReporter problemReporter, MatchLocator locator) {
 	super(problemReporter, true);
-
+	this.reportOnlyOneSyntaxError = true;
 	this.patternLocator = locator.patternLocator;
 	if ((locator.matchContainer & PatternLocator.CLASS_CONTAINER) != 0) {
 		this.localDeclarationVisitor = (locator.matchContainer & PatternLocator.METHOD_CONTAINER) != 0
diff --git a/search/org/eclipse/jdt/internal/core/search/processing/JobManager.java b/search/org/eclipse/jdt/internal/core/search/processing/JobManager.java
index 835ac31..1375e3a 100644
--- a/search/org/eclipse/jdt/internal/core/search/processing/JobManager.java
+++ b/search/org/eclipse/jdt/internal/core/search/processing/JobManager.java
@@ -28,8 +28,9 @@
 	/* background processing */
 	protected Thread processingThread;
 
-	/* flag indicating whether job execution is enabled or not */
-	private boolean enabled = true;
+	/* counter indicating whether job execution is enabled or not, disabled if <= 0 
+	    it cannot go beyond 1 */
+	private int enableCount = 1;
 
 	public static boolean VERBOSE = false;
 	/* flag indicating that the activation has completed */
@@ -55,12 +56,12 @@
 	 * Until the job has completed, the job manager will keep answering the same job.
 	 */
 	public synchronized IJob currentJob() {
-		if (this.enabled && this.jobStart <= this.jobEnd)
+		if (this.enableCount > 0 && this.jobStart <= this.jobEnd)
 			return this.awaitingJobs[this.jobStart];
 		return null;
 	}
 	public void disable() {
-		this.enabled = false;
+		this.enableCount--;
 		if (VERBOSE)
 			Util.verbose("DISABLING background indexing"); //$NON-NLS-1$
 	}
@@ -73,7 +74,6 @@
 		if (VERBOSE)
 			Util.verbose("DISCARD   background job family - " + jobFamily); //$NON-NLS-1$
 
-		boolean wasEnabled = isEnabled();
 		try {
 			IJob currentJob;
 			// cancel current job if it belongs to the given family
@@ -114,21 +114,17 @@
 				this.jobEnd = loc;
 			}
 		} finally {
-			if (wasEnabled)
-				enable();
+			enable();
 		}
 		if (VERBOSE)
 			Util.verbose("DISCARD   DONE with background job family - " + jobFamily); //$NON-NLS-1$
 	}
 	public synchronized void enable() {
-		this.enabled = true;
+		this.enableCount++;
 		if (VERBOSE)
 			Util.verbose("ENABLING  background indexing"); //$NON-NLS-1$
 		this.notifyAll(); // wake up the background thread if it is waiting (context must be synchronized)			
 	}
-	public boolean isEnabled() {
-		return this.enabled;
-	}
 	/**
 	 * Advance to the next available job, once the current one has been completed.
 	 * Note: clients awaiting until the job count is zero are still waiting at this point.
@@ -181,13 +177,11 @@
 				case IJob.ForceImmediate :
 					if (VERBOSE)
 						Util.verbose("-> NOT READY - forcing immediate - " + searchJob);//$NON-NLS-1$
-					boolean wasEnabled = isEnabled();
 					try {
 						disable(); // pause indexing
 						status = searchJob.execute(progress == null ? null : new SubProgressMonitor(progress, concurrentJobWork));
 					} finally {
-						if (wasEnabled)
-							enable();
+						enable();
 					}
 					if (VERBOSE)
 						Util.verbose("FINISHED  concurrent job - " + searchJob); //$NON-NLS-1$
@@ -427,7 +421,7 @@
 	}
 	public String toString() {
 		StringBuffer buffer = new StringBuffer(10);
-		buffer.append("Enabled:").append(this.enabled).append('\n'); //$NON-NLS-1$
+		buffer.append("Enable count:").append(this.enableCount).append('\n'); //$NON-NLS-1$
 		int numJobs = this.jobEnd - this.jobStart + 1;
 		buffer.append("Jobs in queue:").append(numJobs).append('\n'); //$NON-NLS-1$
 		for (int i = 0; i < numJobs && i < 15; i++) {